root/sys/rwlock.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


    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

/* [<][>][^][v][top][bottom][index][help] */