Home | History | Annotate | Download | only in linux
      1 /* rwsem.h: R/W semaphores, public interface
      2  *
      3  * Written by David Howells (dhowells (at) redhat.com).
      4  * Derived from asm-i386/semaphore.h
      5  */
      6 
      7 #ifndef _LINUX_RWSEM_H
      8 #define _LINUX_RWSEM_H
      9 
     10 #include <linux/linkage.h>
     11 
     12 #ifdef __KERNEL__
     13 
     14 #include <linux/types.h>
     15 #include <linux/kernel.h>
     16 #include <asm/system.h>
     17 #include <asm/atomic.h>
     18 
     19 struct rw_semaphore;
     20 
     21 #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
     22 #include <linux/rwsem-spinlock.h> /* use a generic implementation */
     23 #else
     24 #include <asm/rwsem.h> /* use an arch-specific implementation */
     25 #endif
     26 
     27 /*
     28  * lock for reading
     29  */
     30 extern void down_read(struct rw_semaphore *sem);
     31 
     32 /*
     33  * trylock for reading -- returns 1 if successful, 0 if contention
     34  */
     35 extern int down_read_trylock(struct rw_semaphore *sem);
     36 
     37 /*
     38  * lock for writing
     39  */
     40 extern void down_write(struct rw_semaphore *sem);
     41 
     42 /*
     43  * trylock for writing -- returns 1 if successful, 0 if contention
     44  */
     45 extern int down_write_trylock(struct rw_semaphore *sem);
     46 
     47 /*
     48  * release a read lock
     49  */
     50 extern void up_read(struct rw_semaphore *sem);
     51 
     52 /*
     53  * release a write lock
     54  */
     55 extern void up_write(struct rw_semaphore *sem);
     56 
     57 /*
     58  * downgrade write lock to read lock
     59  */
     60 extern void downgrade_write(struct rw_semaphore *sem);
     61 
     62 #ifdef CONFIG_DEBUG_LOCK_ALLOC
     63 /*
     64  * nested locking. NOTE: rwsems are not allowed to recurse
     65  * (which occurs if the same task tries to acquire the same
     66  * lock instance multiple times), but multiple locks of the
     67  * same lock class might be taken, if the order of the locks
     68  * is always the same. This ordering rule can be expressed
     69  * to lockdep via the _nested() APIs, but enumerating the
     70  * subclasses that are used. (If the nesting relationship is
     71  * static then another method for expressing nested locking is
     72  * the explicit definition of lock class keys and the use of
     73  * lockdep_set_class() at lock initialization time.
     74  * See Documentation/lockdep-design.txt for more details.)
     75  */
     76 extern void down_read_nested(struct rw_semaphore *sem, int subclass);
     77 extern void down_write_nested(struct rw_semaphore *sem, int subclass);
     78 /*
     79  * Take/release a lock when not the owner will release it.
     80  *
     81  * [ This API should be avoided as much as possible - the
     82  *   proper abstraction for this case is completions. ]
     83  */
     84 extern void down_read_non_owner(struct rw_semaphore *sem);
     85 extern void up_read_non_owner(struct rw_semaphore *sem);
     86 #else
     87 # define down_read_nested(sem, subclass)		down_read(sem)
     88 # define down_write_nested(sem, subclass)	down_write(sem)
     89 # define down_read_non_owner(sem)		down_read(sem)
     90 # define up_read_non_owner(sem)			up_read(sem)
     91 #endif
     92 
     93 #endif /* __KERNEL__ */
     94 #endif /* _LINUX_RWSEM_H */
     95