[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     ! 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