2 * This code copied from linux kernel 3.11+
3 * commit cb65537ee1134d3cc55c1fa83952bc8eb1212833
10 #if LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0)
12 #include <linux/wait.h>
13 #include <linux/module.h>
16 #define WAIT_ATOMIC_T_BIT_NR -1
17 #define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \
18 { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, }
22 * Manipulate the atomic_t address to produce a better bit waitqueue table hash
23 * index (we're keying off bit -1, but that would produce a horrible hash
26 static inline wait_queue_head_t *atomic_t_waitqueue(atomic_t *p)
28 if (BITS_PER_LONG == 64) {
29 unsigned long q = (unsigned long)p;
30 return bit_waitqueue((void *)(q & ~1), q & 1);
32 return bit_waitqueue(p, 0);
35 static int wake_atomic_t_function(wait_queue_t *wait, unsigned mode, int sync,
38 struct wait_bit_key *key = arg;
39 struct wait_bit_queue *wait_bit
40 = container_of(wait, struct wait_bit_queue, wait);
41 atomic_t *val = key->flags;
43 if (wait_bit->key.flags != key->flags ||
44 wait_bit->key.bit_nr != key->bit_nr ||
45 atomic_read(val) != 0)
47 return autoremove_wake_function(wait, mode, sync, key);
51 * To allow interruptible waiting and asynchronous (i.e. nonblocking) waiting,
52 * the actions of __wait_on_atomic_t() are permitted return codes. Nonzero
53 * return codes halt waiting and return.
55 static int __wait_on_atomic_t(wait_queue_head_t *wq, struct wait_bit_queue *q,
56 int (*action)(atomic_t *), unsigned mode)
62 prepare_to_wait(wq, &q->wait, mode);
64 if (atomic_read(val) == 0)
66 } while (!ret && atomic_read(val) != 0);
67 finish_wait(wq, &q->wait);
71 #define DEFINE_WAIT_ATOMIC_T(name, p) \
72 struct wait_bit_queue name = { \
73 .key = __WAIT_ATOMIC_T_KEY_INITIALIZER(p), \
76 .func = wake_atomic_t_function, \
78 LIST_HEAD_INIT((name).wait.task_list), \
82 int out_of_line_wait_on_atomic_t(atomic_t *p, int (*action)(atomic_t *),
85 wait_queue_head_t *wq = atomic_t_waitqueue(p);
86 DEFINE_WAIT_ATOMIC_T(wait, p);
88 return __wait_on_atomic_t(wq, &wait, action, mode);
90 EXPORT_SYMBOL(out_of_line_wait_on_atomic_t);
93 * wake_up_atomic_t - Wake up a waiter on a atomic_t
94 * @word: The word being waited on, a kernel virtual address
95 * @bit: The bit of the word being waited on
97 * Wake up anyone waiting for the atomic_t to go to zero.
99 * Abuse the bit-waker function and its waitqueue hash table set (the atomic_t
100 * check is done by the waiter's wake function, not the by the waker itself).
102 void wake_up_atomic_t(atomic_t *p)
104 __wake_up_bit(atomic_t_waitqueue(p), p, WAIT_ATOMIC_T_BIT_NR);
106 EXPORT_SYMBOL(wake_up_atomic_t);
108 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(3, 11, 0) */