1 /* rwsem.h: R/W semaphores, public interface
3 * Written by David Howells (dhowells@redhat.com).
4 * Derived from asm-i386/semaphore.h
10 #include <linux/linkage.h>
12 #ifdef CONFIG_PREEMPT_RT
13 # include <linux/rt_lock.h>
16 #include <linux/types.h>
17 #include <linux/kernel.h>
18 #include <asm/system.h>
19 #include <asm/atomic.h>
21 #ifndef CONFIG_PREEMPT_RT
23 * On !PREEMPT_RT all rw-semaphores are compat:
25 #define compat_rw_semaphore rw_semaphore
28 struct compat_rw_semaphore
;
30 #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
31 # include <linux/rwsem-spinlock.h> /* use a generic implementation */
32 # ifndef CONFIG_PREEMPT_RT
33 # define __RWSEM_INITIALIZER __COMPAT_RWSEM_INITIALIZER
34 # define DECLARE_RWSEM COMPAT_DECLARE_RWSEM
37 # include <asm/rwsem.h> /* use an arch-specific implementation */
43 extern void compat_down_read(struct compat_rw_semaphore
*sem
);
46 * trylock for reading -- returns 1 if successful, 0 if contention
48 extern int compat_down_read_trylock(struct compat_rw_semaphore
*sem
);
53 extern void compat_down_write(struct compat_rw_semaphore
*sem
);
56 * trylock for writing -- returns 1 if successful, 0 if contention
58 extern int compat_down_write_trylock(struct compat_rw_semaphore
*sem
);
63 extern void compat_up_read(struct compat_rw_semaphore
*sem
);
66 * release a write lock
68 extern void compat_up_write(struct compat_rw_semaphore
*sem
);
71 * downgrade write lock to read lock
73 extern void compat_downgrade_write(struct compat_rw_semaphore
*sem
);
75 #ifdef CONFIG_DEBUG_LOCK_ALLOC
77 * nested locking. NOTE: rwsems are not allowed to recurse
78 * (which occurs if the same task tries to acquire the same
79 * lock instance multiple times), but multiple locks of the
80 * same lock class might be taken, if the order of the locks
81 * is always the same. This ordering rule can be expressed
82 * to lockdep via the _nested() APIs, but enumerating the
83 * subclasses that are used. (If the nesting relationship is
84 * static then another method for expressing nested locking is
85 * the explicit definition of lock class keys and the use of
86 * lockdep_set_class() at lock initialization time.
87 * See Documentation/lockdep-design.txt for more details.)
90 compat_down_read_nested(struct compat_rw_semaphore
*sem
, int subclass
);
92 compat_down_write_nested(struct compat_rw_semaphore
*sem
, int subclass
);
94 * Take/release a lock when not the owner will release it.
96 * [ This API should be avoided as much as possible - the
97 * proper abstraction for this case is completions. ]
100 compat_down_read_non_owner(struct compat_rw_semaphore
*sem
);
102 compat_up_read_non_owner(struct compat_rw_semaphore
*sem
);
104 # define compat_down_read_nested(sem, subclass) compat_down_read(sem)
105 # define compat_down_write_nested(sem, subclass) compat_down_write(sem)
106 # define compat_down_read_non_owner(sem) compat_down_read(sem)
107 # define compat_up_read_non_owner(sem) compat_up_read(sem)
110 #ifndef CONFIG_PREEMPT_RT
112 #define DECLARE_RWSEM COMPAT_DECLARE_RWSEM
115 * NOTE, lockdep: this has to be a macro, so that separate class-keys
116 * get generated by the compiler, if the same function does multiple
117 * init_rwsem() calls to different rwsems.
119 #define init_rwsem(rwsem) compat_init_rwsem(rwsem)
121 static inline void down_read(struct compat_rw_semaphore
*rwsem
)
123 compat_down_read(rwsem
);
125 static inline int down_read_trylock(struct compat_rw_semaphore
*rwsem
)
127 return compat_down_read_trylock(rwsem
);
129 static inline void down_write(struct compat_rw_semaphore
*rwsem
)
131 compat_down_write(rwsem
);
133 static inline int down_write_trylock(struct compat_rw_semaphore
*rwsem
)
135 return compat_down_write_trylock(rwsem
);
137 static inline void up_read(struct compat_rw_semaphore
*rwsem
)
139 compat_up_read(rwsem
);
141 static inline void up_write(struct compat_rw_semaphore
*rwsem
)
143 compat_up_write(rwsem
);
145 static inline void downgrade_write(struct compat_rw_semaphore
*rwsem
)
147 compat_downgrade_write(rwsem
);
149 static inline int rwsem_is_locked(struct compat_rw_semaphore
*sem
)
151 return compat_rwsem_is_locked(sem
);
153 # define down_read_nested(sem, subclass) \
154 compat_down_read_nested(sem, subclass)
155 # define down_write_nested(sem, subclass) \
156 compat_down_write_nested(sem, subclass)
157 # define down_read_non_owner(sem) \
158 compat_down_read_non_owner(sem)
159 # define up_read_non_owner(sem) \
160 compat_up_read_non_owner(sem)
161 #endif /* !CONFIG_PREEMPT_RT */
163 #endif /* _LINUX_RWSEM_H */