diff options
Diffstat (limited to 'include/linux/wait.h')
-rw-r--r-- | include/linux/wait.h | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/include/linux/wait.h b/include/linux/wait.h index ac38be2692d8..5bacfc4b336d 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -23,6 +23,7 @@ struct __wait_queue { | |||
23 | struct wait_bit_key { | 23 | struct wait_bit_key { |
24 | void *flags; | 24 | void *flags; |
25 | int bit_nr; | 25 | int bit_nr; |
26 | #define WAIT_ATOMIC_T_BIT_NR -1 | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct wait_bit_queue { | 29 | struct wait_bit_queue { |
@@ -60,6 +61,9 @@ struct task_struct; | |||
60 | #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ | 61 | #define __WAIT_BIT_KEY_INITIALIZER(word, bit) \ |
61 | { .flags = word, .bit_nr = bit, } | 62 | { .flags = word, .bit_nr = bit, } |
62 | 63 | ||
64 | #define __WAIT_ATOMIC_T_KEY_INITIALIZER(p) \ | ||
65 | { .flags = p, .bit_nr = WAIT_ATOMIC_T_BIT_NR, } | ||
66 | |||
63 | extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *); | 67 | extern void __init_waitqueue_head(wait_queue_head_t *q, const char *name, struct lock_class_key *); |
64 | 68 | ||
65 | #define init_waitqueue_head(q) \ | 69 | #define init_waitqueue_head(q) \ |
@@ -146,8 +150,10 @@ void __wake_up_bit(wait_queue_head_t *, void *, int); | |||
146 | int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); | 150 | int __wait_on_bit(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); |
147 | int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); | 151 | int __wait_on_bit_lock(wait_queue_head_t *, struct wait_bit_queue *, int (*)(void *), unsigned); |
148 | void wake_up_bit(void *, int); | 152 | void wake_up_bit(void *, int); |
153 | void wake_up_atomic_t(atomic_t *); | ||
149 | int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); | 154 | int out_of_line_wait_on_bit(void *, int, int (*)(void *), unsigned); |
150 | int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); | 155 | int out_of_line_wait_on_bit_lock(void *, int, int (*)(void *), unsigned); |
156 | int out_of_line_wait_on_atomic_t(atomic_t *, int (*)(atomic_t *), unsigned); | ||
151 | wait_queue_head_t *bit_waitqueue(void *, int); | 157 | wait_queue_head_t *bit_waitqueue(void *, int); |
152 | 158 | ||
153 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) | 159 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) |
@@ -896,5 +902,23 @@ static inline int wait_on_bit_lock(void *word, int bit, | |||
896 | return 0; | 902 | return 0; |
897 | return out_of_line_wait_on_bit_lock(word, bit, action, mode); | 903 | return out_of_line_wait_on_bit_lock(word, bit, action, mode); |
898 | } | 904 | } |
905 | |||
906 | /** | ||
907 | * wait_on_atomic_t - Wait for an atomic_t to become 0 | ||
908 | * @val: The atomic value being waited on, a kernel virtual address | ||
909 | * @action: the function used to sleep, which may take special actions | ||
910 | * @mode: the task state to sleep in | ||
911 | * | ||
912 | * Wait for an atomic_t to become 0. We abuse the bit-wait waitqueue table for | ||
913 | * the purpose of getting a waitqueue, but we set the key to a bit number | ||
914 | * outside of the target 'word'. | ||
915 | */ | ||
916 | static inline | ||
917 | int wait_on_atomic_t(atomic_t *val, int (*action)(atomic_t *), unsigned mode) | ||
918 | { | ||
919 | if (atomic_read(val) == 0) | ||
920 | return 0; | ||
921 | return out_of_line_wait_on_atomic_t(val, action, mode); | ||
922 | } | ||
899 | 923 | ||
900 | #endif | 924 | #endif |