1 /* rwsem.h: R/W semaphores, public interface
2 *
3 * Written by David Howells (dhowells@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 CONFIG_PREEMPT_RT
13 # include <linux/rt_lock.h>
14 #endif
15
16 #ifdef __KERNEL__
17
18 #include <linux/types.h>
19 #include <linux/kernel.h>
20 #include <asm/system.h>
21 #include <asm/atomic.h>
22
23 #ifndef CONFIG_PREEMPT_RT
24 /*
25 * On !PREEMPT_RT all rw-semaphores are compat:
26 */
27 #define compat_rw_semaphore rw_semaphore
28 #endif
29
30 struct compat_rw_semaphore;
31
32 #ifdef CONFIG_RWSEM_GENERIC_SPINLOCK
33 # include <linux/rwsem-spinlock.h> /* use a generic implementation */
34 # ifndef CONFIG_PREEMPT_RT
35 # define __RWSEM_INITIALIZER __COMPAT_RWSEM_INITIALIZER
36 # define DECLARE_RWSEM COMPAT_DECLARE_RWSEM
37 # endif
38 #else
39 # include <asm/rwsem.h> /* use an arch-specific implementation */
40 #endif
41
42 /*
43 * lock for reading
44 */
45 extern void compat_down_read(struct compat_rw_semaphore *sem);
46
47 /*
48 * trylock for reading -- returns 1 if successful, 0 if contention
49 */
50 extern int compat_down_read_trylock(struct compat_rw_semaphore *sem);
51
52 /*
53 * lock for writing
54 */
55 extern void compat_down_write(struct compat_rw_semaphore *sem);
56
57 /*
58 * trylock for writing -- returns 1 if successful, 0 if contention
59 */
60 extern int compat_down_write_trylock(struct compat_rw_semaphore *sem);
61
62 /*
63 * release a read lock
64 */
65 extern void compat_up_read(struct compat_rw_semaphore *sem);
66
67 /*
68 * release a write lock
69 */
70 extern void compat_up_write(struct compat_rw_semaphore *sem);
71
72 /*
73 * downgrade write lock to read lock
74 */
75 extern void compat_downgrade_write(struct compat_rw_semaphore *sem);
76
77 #ifdef CONFIG_DEBUG_LOCK_ALLOC
78 /*
79 * nested locking. NOTE: rwsems are not allowed to recurse
80 * (which occurs if the same task tries to acquire the same
81 * lock instance multiple times), but multiple locks of the
82 * same lock class might be taken, if the order of the locks
83 * is always the same. This ordering rule can be expressed
84 * to lockdep via the _nested() APIs, but enumerating the
85 * subclasses that are used. (If the nesting relationship is
86 * static then another method for expressing nested locking is
87 * the explicit definition of lock class keys and the use of
88 * lockdep_set_class() at lock initialization time.
89 * See Documentation/lockdep-design.txt for more details.)
90 */
91 extern void
92 compat_down_read_nested(struct compat_rw_semaphore *sem, int subclass);
93 extern void
94 compat_down_write_nested(struct compat_rw_semaphore *sem, int subclass);
95 /*
96 * Take/release a lock when not the owner will release it.
97 *
98 * [ This API should be avoided as much as possible - the
99 * proper abstraction for this case is completions. ]
100 */
101 extern void
102 compat_down_read_non_owner(struct compat_rw_semaphore *sem);
103 extern void
104 compat_up_read_non_owner(struct compat_rw_semaphore *sem);
105 #else
106 # define compat_down_read_nested(sem, subclass) compat_down_read(sem)
107 # define compat_down_write_nested(sem, subclass) compat_down_write(sem)
108 # define compat_down_read_non_owner(sem) compat_down_read(sem)
109 # define compat_up_read_non_owner(sem) compat_up_read(sem)
110 #endif
111
112 #ifndef CONFIG_PREEMPT_RT
113
114 #define DECLARE_RWSEM COMPAT_DECLARE_RWSEM
115
116 /*
117 * NOTE, lockdep: this has to be a macro, so that separate class-keys
118 * get generated by the compiler, if the same function does multiple
119 * init_rwsem() calls to different rwsems.
120 */
121 #define init_rwsem(rwsem) compat_init_rwsem(rwsem)
122
123 static inline void down_read(struct compat_rw_semaphore *rwsem)
124 {
125 compat_down_read(rwsem);
126 }
127 static inline int down_read_trylock(struct compat_rw_semaphore *rwsem)
128 {
129 return compat_down_read_trylock(rwsem);
130 }
131 static inline void down_write(struct compat_rw_semaphore *rwsem)
132 {
133 compat_down_write(rwsem);
134 }
135 static inline int down_write_trylock(struct compat_rw_semaphore *rwsem)
136 {
137 return compat_down_write_trylock(rwsem);
138 }
139 static inline void up_read(struct compat_rw_semaphore *rwsem)
140 {
141 compat_up_read(rwsem);
142 }
143 static inline void up_write(struct compat_rw_semaphore *rwsem)
144 {
145 compat_up_write(rwsem);
146 }
147 static inline void downgrade_write(struct compat_rw_semaphore *rwsem)
148 {
149 compat_downgrade_write(rwsem);
150 }
151 static inline int rwsem_is_locked(struct compat_rw_semaphore *sem)
152 {
153 return compat_rwsem_is_locked(sem);
154 }
155 # define down_read_nested(sem, subclass) \
156 compat_down_read_nested(sem, subclass)
157 # define down_write_nested(sem, subclass) \
158 compat_down_write_nested(sem, subclass)
159 # define down_read_non_owner(sem) \
160 compat_down_read_non_owner(sem)
161 # define up_read_non_owner(sem) \
162 compat_up_read_non_owner(sem)
163 #endif /* !CONFIG_PREEMPT_RT */
164
165 #endif /* __KERNEL__ */
166 #endif /* _LINUX_RWSEM_H */
167
|
This page was automatically generated by the
LXR engine.
|