[BACK]Return to rwlock.h CVS log [TXT][DIR] Up to [local] / sys / sys

Annotation of sys/sys/rwlock.h, Revision 1.1.1.1

1.1       nbrk        1: /*     $OpenBSD: rwlock.h,v 1.11 2007/05/29 00:17:32 thib Exp $        */
                      2: /*
                      3:  * Copyright (c) 2002 Artur Grabowski <art@openbsd.org>
                      4:  * All rights reserved.
                      5:  *
                      6:  * Redistribution and use in source and binary forms, with or without
                      7:  * modification, are permitted provided that the following conditions
                      8:  * are met:
                      9:  *
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. The name of the author may not be used to endorse or promote products
                     13:  *    derived from this software without specific prior written permission.
                     14:  *
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
                     16:  * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
                     17:  * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
                     18:  * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
                     19:  * EXEMPLARY, OR CONSEQUENTIAL  DAMAGES (INCLUDING, BUT NOT LIMITED TO,
                     20:  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
                     21:  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
                     22:  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
                     23:  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
                     24:  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
                     25:  */
                     26:
                     27: /*
                     28:  * Multiple readers, single writer lock.
                     29:  *
                     30:  * Simplistic implementation modelled after rw locks in Solaris.
                     31:  *
                     32:  * The rwl_owner has the following layout:
                     33:  * [ owner or count of readers | wrlock | wrwant | wait ]
                     34:  *
                     35:  * When the WAIT bit is set (bit 0), the lock has waiters sleeping on it.
                     36:  * When the WRWANT bit is set (bit 1), at least one waiter wants a write lock.
                     37:  * When the WRLOCK bit is set (bit 2) the lock is currently write-locked.
                     38:  *
                     39:  * When write locked, the upper bits contain the struct proc * pointer to
                     40:  * the writer, otherwise they count the number of readers.
                     41:  *
                     42:  * We provide a simple machine independent implementation that can be
                     43:  * optimized by machine dependent code when __HAVE_MD_RWLOCK is defined.
                     44:  *
                     45:  * MD code that defines __HAVE_MD_RWLOCK and implement four functions:
                     46:  *
                     47:  * void rw_enter_read(struct rwlock *)
                     48:  *  atomically test for RWLOCK_WRLOCK and if not set, increment the lock
                     49:  *  by RWLOCK_READ_INCR. While RWLOCK_WRLOCK is set, loop into rw_enter_wait.
                     50:  *
                     51:  * void rw_enter_write(struct rwlock *);
                     52:  *  atomically test for the lock being 0 (it's not possible to have
                     53:  *  owner/read count unset and waiter bits set) and if 0 set the owner to
                     54:  *  the proc and RWLOCK_WRLOCK. While not zero, loop into rw_enter_wait.
                     55:  *
                     56:  * void rw_exit_read(struct rwlock *);
                     57:  *  atomically decrement lock by RWLOCK_READ_INCR and unset RWLOCK_WAIT and
                     58:  *  RWLOCK_WRWANT remembering the old value of lock and if RWLOCK_WAIT was set,
                     59:  *  call rw_exit_waiters with the old contents of the lock.
                     60:  *
                     61:  * void rw_exit_write(struct rwlock *);
                     62:  *  atomically swap the contents of the lock with 0 and if RWLOCK_WAIT was
                     63:  *  set, call rw_exit_waiters with the old contents of the lock.
                     64:  *
                     65:  * (XXX - the rest of the API for this is not invented yet).
                     66:  */
                     67:
                     68: #ifndef SYS_RWLOCK_H
                     69: #define SYS_RWLOCK_H
                     70:
                     71:
                     72: struct proc;
                     73:
                     74: struct rwlock {
                     75:        __volatile unsigned long rwl_owner;
                     76:        const char *rwl_name;
                     77: };
                     78:
                     79: #define RWLOCK_INITIALIZER(name)       { 0, name }
                     80:
                     81: #define RWLOCK_WAIT            0x01UL
                     82: #define RWLOCK_WRWANT          0x02UL
                     83: #define RWLOCK_WRLOCK          0x04UL
                     84: #define RWLOCK_MASK            0x07UL
                     85:
                     86: #define RWLOCK_OWNER(rwl)      ((struct proc *)((rwl)->rwl_owner & ~RWLOCK_MASK))
                     87:
                     88: #define RWLOCK_READER_SHIFT    3UL
                     89: #define RWLOCK_READ_INCR       (1UL << RWLOCK_READER_SHIFT)
                     90:
                     91: void rw_init(struct rwlock *, const char *);
                     92:
                     93: void rw_enter_read(struct rwlock *);
                     94: void rw_enter_write(struct rwlock *);
                     95: void rw_exit_read(struct rwlock *);
                     96: void rw_exit_write(struct rwlock *);
                     97:
                     98: int rw_enter(struct rwlock *, int);
                     99: void rw_exit(struct rwlock *);
                    100: #define RW_WRITE       0x00UL          /* exclusive lock */
                    101: #define RW_READ                0x01UL          /* shared lock */
                    102: #define RW_DOWNGRADE   0x02UL          /* downgrade exclusive to shared */
                    103: #define RW_OPMASK      0x03UL
                    104:
                    105: #define RW_INTR                0x10UL          /* interruptible sleep */
                    106: #define RW_SLEEPFAIL   0x20UL          /* fail if we slept for the lock */
                    107: #define RW_NOSLEEP     0x40UL          /* don't wait for the lock */
                    108:
                    109: #ifndef rw_cas
                    110: int rw_cas(volatile unsigned long *, unsigned long, unsigned long);
                    111: #endif
                    112:
                    113: #endif

CVSweb