LCOV - code coverage report
Current view: top level - include/linux - wait_bit.h (source / functions) Hit Total Coverage
Test: combined.info Lines: 11 25 44.0 %
Date: 2022-03-28 15:32:58 Functions: 3 5 60.0 %
Branches: 4 10 40.0 %

           Branch data     Line data    Source code
       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                 :       7348 : wait_on_bit(unsigned long *word, int bit, unsigned mode)
      72                 :            : {
      73                 :       7348 :         might_sleep();
      74         [ -  + ]:       7348 :         if (!test_bit(bit, word))
      75                 :            :                 return 0;
      76                 :          0 :         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                 :       3521 : wait_on_bit_io(unsigned long *word, int bit, unsigned mode)
      97                 :            : {
      98                 :       3521 :         might_sleep();
      99         [ +  + ]:       3521 :         if (!test_bit(bit, word))
     100                 :            :                 return 0;
     101                 :       3518 :         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(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                 :          0 : wait_on_bit_action(unsigned long *word, int bit, wait_bit_action_f *action,
     151                 :            :                    unsigned mode)
     152                 :            : {
     153                 :          0 :         might_sleep();
     154         [ #  # ]:          0 :         if (!test_bit(bit, word))
     155                 :            :                 return 0;
     156                 :          0 :         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                 :          0 : wait_on_bit_lock(unsigned long *word, int bit, unsigned mode)
     180                 :            : {
     181                 :          0 :         might_sleep();
     182         [ #  # ]:          0 :         if (!test_and_set_bit(bit, word))
     183                 :            :                 return 0;
     184                 :          0 :         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                 :         64 : wait_on_bit_lock_io(unsigned long *word, int bit, unsigned mode)
     204                 :            : {
     205                 :         64 :         might_sleep();
     206         [ +  - ]:         64 :         if (!test_and_set_bit(bit, word))
     207                 :            :                 return 0;
     208                 :         64 :         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                 :          0 : static inline void clear_and_wake_up_bit(int bit, void *word)
     331                 :            : {
     332                 :          0 :         clear_bit_unlock(bit, word);
     333                 :            :         /* See wake_up_bit() for which memory barrier you need to use. */
     334                 :          0 :         smp_mb__after_atomic();
     335                 :          0 :         wake_up_bit(word, bit);
     336                 :          0 : }
     337                 :            : 
     338                 :            : #endif /* _LINUX_WAIT_BIT_H */

Generated by: LCOV version 1.14