~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/include/linux/wait_bit.h

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _LINUX_WAIT_BIT_H
  3 #define _LINUX_WAIT_BIT_H
  4 
  5 /*
  6  * Linux wait-bit related types and methods:
  7  */
  8 #include <linux/wait.h>
  9 
 10 struct wait_bit_key {
 11         void                    *flags;
 12         int                     bit_nr;
 13         unsigned long           timeout;
 14 };
 15 
 16 struct wait_bit_queue_entry {
 17         struct wait_bit_key     key;
 18         struct wait_queue_entry wq_entry;
 19 };
 20 
 21 #define __WAIT_BIT_KEY_INITIALIZER(word, bit)                                   \
 22         { .flags = word, .bit_nr = bit, }
 23 
 24 typedef int wait_bit_action_f(struct wait_bit_key *key, int mode);
 25 
 26 void __wake_up_bit(struct wait_queue_head *wq_head, void *word, int bit);
 27 int __wait_on_bit(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
 28 int __wait_on_bit_lock(struct wait_queue_head *wq_head, struct wait_bit_queue_entry *wbq_entry, wait_bit_action_f *action, unsigned int mode);
 29 void wake_up_bit(void *word, int bit);
 30 int out_of_line_wait_on_bit(void *word, int, wait_bit_action_f *action, unsigned int mode);
 31 int out_of_line_wait_on_bit_timeout(void *word, int, wait_bit_action_f *action, unsigned int mode, unsigned long timeout);
 32 int out_of_line_wait_on_bit_lock(void *word, int, wait_bit_action_f *action, unsigned int mode);
 33 struct wait_queue_head *bit_waitqueue(void *word, int bit);
 34 extern void __init wait_bit_init(void);
 35 
 36 int wake_bit_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key);
 37 
 38 #define DEFINE_WAIT_BIT(name, word, bit)                                        \
 39         struct wait_bit_queue_entry name = {                                    \
 40                 .key = __WAIT_BIT_KEY_INITIALIZER(word, bit),                   \
 41                 .wq_entry = {                                                   \
 42                         .private        = current,                              \
 43                         .func           = wake_bit_function,                    \
 44                         .entry          =                                       \
 45                                 LIST_HEAD_INIT((name).wq_entry.entry),          \
 46                 },                                                              \
 47         }
 48 
 49 extern int bit_wait(struct wait_bit_key *key, int mode);
 50 extern int bit_wait_io(struct wait_bit_key *key, int mode);
 51 extern int bit_wait_timeout(struct wait_bit_key *key, int mode);
 52 extern int bit_wait_io_timeout(struct wait_bit_key *key, int mode);
 53 
 54 /**
 55  * wait_on_bit - wait for a bit to be cleared
 56  * @word: the word being waited on, a kernel virtual address
 57  * @bit: the bit of the word being waited on
 58  * @mode: the task state to sleep in
 59  *
 60  * There is a standard hashed waitqueue table for generic use. This
 61  * is the part of the hashtable's accessor API that waits on a bit.
 62  * For instance, if one were to have waiters on a bitflag, one would
 63  * call wait_on_bit() in threads waiting for the bit to clear.
 64  * One uses wait_on_bit() where one is waiting for the bit to clear,
 65  * but has no intention of setting it.
 66  * Returned value will be zero if the bit was cleared, or non-zero
 67  * if the process received a signal and the mode permitted wakeup
 68  * on that signal.
 69  */
 70 static inline int
 71 wait_on_bit(unsigned long *word, int bit, unsigned mode)
 72 {
 73         might_sleep();
 74         if (!test_bit_acquire(bit, word))
 75                 return 0;
 76         return out_of_line_wait_on_bit(word, bit,
 77                                        bit_wait,
 78                                        mode);
 79 }
 80 
 81 /**
 82  * wait_on_bit_io - wait for a bit to be cleared
 83  * @word: the word being waited on, a kernel virtual address
 84  * @bit: the bit of the word being waited on
 85  * @mode: the task state to sleep in
 86  *
 87  * Use the standard hashed waitqueue table to wait for a bit
 88  * to be cleared.  This is similar to wait_on_bit(), but calls
 89  * io_schedule() instead of schedule() for the actual waiting.
 90  *
 91  * Returned value will be zero if the bit was cleared, or non-zero
 92  * if the process received a signal and the mode permitted wakeup
 93  * on that signal.
 94  */
 95 static inline int
 96 wait_on_bit_io(unsigned long *word, int bit, unsigned mode)
 97 {
 98         might_sleep();
 99         if (!test_bit_acquire(bit, word))
100                 return 0;
101         return out_of_line_wait_on_bit(word, bit,
102                                        bit_wait_io,
103                                        mode);
104 }
105 
106 /**
107  * wait_on_bit_timeout - wait for a bit to be cleared or a timeout elapses
108  * @word: the word being waited on, a kernel virtual address
109  * @bit: the bit of the word being waited on
110  * @mode: the task state to sleep in
111  * @timeout: timeout, in jiffies
112  *
113  * Use the standard hashed waitqueue table to wait for a bit
114  * to be cleared. This is similar to wait_on_bit(), except also takes a
115  * timeout parameter.
116  *
117  * Returned value will be zero if the bit was cleared before the
118  * @timeout elapsed, or non-zero if the @timeout elapsed or process
119  * received a signal and the mode permitted wakeup on that signal.
120  */
121 static inline int
122 wait_on_bit_timeout(unsigned long *word, int bit, unsigned mode,
123                     unsigned long timeout)
124 {
125         might_sleep();
126         if (!test_bit_acquire(bit, word))
127                 return 0;
128         return out_of_line_wait_on_bit_timeout(word, bit,
129                                                bit_wait_timeout,
130                                                mode, timeout);
131 }
132 
133 /**
134  * wait_on_bit_action - wait for a bit to be cleared
135  * @word: the word being waited on, a kernel virtual address
136  * @bit: the bit of the word being waited on
137  * @action: the function used to sleep, which may take special actions
138  * @mode: the task state to sleep in
139  *
140  * Use the standard hashed waitqueue table to wait for a bit
141  * to be cleared, and allow the waiting action to be specified.
142  * This is like wait_on_bit() but allows fine control of how the waiting
143  * is done.
144  *
145  * Returned value will be zero if the bit was cleared, or non-zero
146  * if the process received a signal and the mode permitted wakeup
147  * on that signal.
148  */
149 static inline int
150 wait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action,
151                    unsigned mode)
152 {
153         might_sleep();
154         if (!test_bit_acquire(bit, word))
155                 return 0;
156         return out_of_line_wait_on_bit(word, bit, action, mode);
157 }
158 
159 /**
160  * wait_on_bit_lock - wait for a bit to be cleared, when wanting to set it
161  * @word: the word being waited on, a kernel virtual address
162  * @bit: the bit of the word being waited on
163  * @mode: the task state to sleep in
164  *
165  * There is a standard hashed waitqueue table for generic use. This
166  * is the part of the hashtable's accessor API that waits on a bit
167  * when one intends to set it, for instance, trying to lock bitflags.
168  * For instance, if one were to have waiters trying to set bitflag
169  * and waiting for it to clear before setting it, one would call
170  * wait_on_bit() in threads waiting to be able to set the bit.
171  * One uses wait_on_bit_lock() where one is waiting for the bit to
172  * clear with the intention of setting it, and when done, clearing it.
173  *
174  * Returns zero if the bit was (eventually) found to be clear and was
175  * set.  Returns non-zero if a signal was delivered to the process and
176  * the @mode allows that signal to wake the process.
177  */
178 static inline int
179 wait_on_bit_lock(unsigned long *word, int bit, unsigned mode)
180 {
181         might_sleep();
182         if (!test_and_set_bit(bit, word))
183                 return 0;
184         return out_of_line_wait_on_bit_lock(word, bit, bit_wait, mode);
185 }
186 
187 /**
188  * wait_on_bit_lock_io - wait for a bit to be cleared, when wanting to set it
189  * @word: the word being waited on, a kernel virtual address
190  * @bit: the bit of the word being waited on
191  * @mode: the task state to sleep in
192  *
193  * Use the standard hashed waitqueue table to wait for a bit
194  * to be cleared and then to atomically set it.  This is similar
195  * to wait_on_bit(), but calls io_schedule() instead of schedule()
196  * for the actual waiting.
197  *
198  * Returns zero if the bit was (eventually) found to be clear and was
199  * set.  Returns non-zero if a signal was delivered to the process and
200  * the @mode allows that signal to wake the process.
201  */
202 static inline int
203 wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode)
204 {
205         might_sleep();
206         if (!test_and_set_bit(bit, word))
207                 return 0;
208         return out_of_line_wait_on_bit_lock(word, bit, bit_wait_io, mode);
209 }
210 
211 /**
212  * wait_on_bit_lock_action - wait for a bit to be cleared, when wanting to set it
213  * @word: the word being waited on, a kernel virtual address
214  * @bit: the bit of the word being waited on
215  * @action: the function used to sleep, which may take special actions
216  * @mode: the task state to sleep in
217  *
218  * Use the standard hashed waitqueue table to wait for a bit
219  * to be cleared and then to set it, and allow the waiting action
220  * to be specified.
221  * This is like wait_on_bit() but allows fine control of how the waiting
222  * is done.
223  *
224  * Returns zero if the bit was (eventually) found to be clear and was
225  * set.  Returns non-zero if a signal was delivered to the process and
226  * the @mode allows that signal to wake the process.
227  */
228 static inline int
229 wait_on_bit_lock_action(unsigned long *word, int bit, wait_bit_action_f *action,
230                         unsigned mode)
231 {
232         might_sleep();
233         if (!test_and_set_bit(bit, word))
234                 return 0;
235         return out_of_line_wait_on_bit_lock(word, bit, action, mode);
236 }
237 
238 extern void init_wait_var_entry(struct wait_bit_queue_entry *wbq_entry, void *var, int flags);
239 extern void wake_up_var(void *var);
240 extern wait_queue_head_t *__var_waitqueue(void *p);
241 
242 #define ___wait_var_event(var, condition, state, exclusive, ret, cmd)   \
243 ({                                                                      \
244         __label__ __out;                                                \
245         struct wait_queue_head *__wq_head = __var_waitqueue(var);       \
246         struct wait_bit_queue_entry __wbq_entry;                        \
247         long __ret = ret; /* explicit shadow */                         \
248                                                                         \
249         init_wait_var_entry(&__wbq_entry, var,                          \
250                             exclusive ? WQ_FLAG_EXCLUSIVE : 0);         \
251         for (;;) {                                                      \
252                 long __int = prepare_to_wait_event(__wq_head,           \
253                                                    &__wbq_entry.wq_entry, \
254                                                    state);              \
255                 if (condition)                                          \
256                         break;                                          \
257                                                                         \
258                 if (___wait_is_interruptible(state) && __int) {         \
259                         __ret = __int;                                  \
260                         goto __out;                                     \
261                 }                                                       \
262                                                                         \
263                 cmd;                                                    \
264         }                                                               \
265         finish_wait(__wq_head, &__wbq_entry.wq_entry);                  \
266 __out:  __ret;                                                          \
267 })
268 
269 #define __wait_var_event(var, condition)                                \
270         ___wait_var_event(var, condition, TASK_UNINTERRUPTIBLE, 0, 0,   \
271                           schedule())
272 
273 #define wait_var_event(var, condition)                                  \
274 do {                                                                    \
275         might_sleep();                                                  \
276         if (condition)                                                  \
277                 break;                                                  \
278         __wait_var_event(var, condition);                               \
279 } while (0)
280 
281 #define __wait_var_event_killable(var, condition)                       \
282         ___wait_var_event(var, condition, TASK_KILLABLE, 0, 0,          \
283                           schedule())
284 
285 #define wait_var_event_killable(var, condition)                         \
286 ({                                                                      \
287         int __ret = 0;                                                  \
288         might_sleep();                                                  \
289         if (!(condition))                                               \
290                 __ret = __wait_var_event_killable(var, condition);      \
291         __ret;                                                          \
292 })
293 
294 #define __wait_var_event_timeout(var, condition, timeout)               \
295         ___wait_var_event(var, ___wait_cond_timeout(condition),         \
296                           TASK_UNINTERRUPTIBLE, 0, timeout,             \
297                           __ret = schedule_timeout(__ret))
298 
299 #define wait_var_event_timeout(var, condition, timeout)                 \
300 ({                                                                      \
301         long __ret = timeout;                                           \
302         might_sleep();                                                  \
303         if (!___wait_cond_timeout(condition))                           \
304                 __ret = __wait_var_event_timeout(var, condition, timeout); \
305         __ret;                                                          \
306 })
307 
308 #define __wait_var_event_interruptible(var, condition)                  \
309         ___wait_var_event(var, condition, TASK_INTERRUPTIBLE, 0, 0,     \
310                           schedule())
311 
312 #define wait_var_event_interruptible(var, condition)                    \
313 ({                                                                      \
314         int __ret = 0;                                                  \
315         might_sleep();                                                  \
316         if (!(condition))                                               \
317                 __ret = __wait_var_event_interruptible(var, condition); \
318         __ret;                                                          \
319 })
320 
321 /**
322  * clear_and_wake_up_bit - clear a bit and wake up anyone waiting on that bit
323  *
324  * @bit: the bit of the word being waited on
325  * @word: the word being waited on, a kernel virtual address
326  *
327  * You can use this helper if bitflags are manipulated atomically rather than
328  * non-atomically under a lock.
329  */
330 static inline void clear_and_wake_up_bit(int bit, void *word)
331 {
332         clear_bit_unlock(bit, word);
333         /* See wake_up_bit() for which memory barrier you need to use. */
334         smp_mb__after_atomic();
335         wake_up_bit(word, bit);
336 }
337 
338 #endif /* _LINUX_WAIT_BIT_H */
339 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php