.. | .. |
---|
7 | 7 | #include <linux/list.h> |
---|
8 | 8 | #include <linux/stddef.h> |
---|
9 | 9 | #include <linux/spinlock.h> |
---|
10 | | -#include <linux/sched/debug.h> |
---|
11 | 10 | |
---|
12 | 11 | #include <asm/current.h> |
---|
13 | 12 | #include <uapi/linux/wait.h> |
---|
| 13 | +#include <linux/atomic.h> |
---|
14 | 14 | |
---|
15 | 15 | typedef struct wait_queue_entry wait_queue_entry_t; |
---|
16 | 16 | |
---|
.. | .. |
---|
21 | 21 | #define WQ_FLAG_EXCLUSIVE 0x01 |
---|
22 | 22 | #define WQ_FLAG_WOKEN 0x02 |
---|
23 | 23 | #define WQ_FLAG_BOOKMARK 0x04 |
---|
| 24 | +#define WQ_FLAG_CUSTOM 0x08 |
---|
| 25 | +#define WQ_FLAG_DONE 0x10 |
---|
24 | 26 | |
---|
25 | 27 | /* |
---|
26 | 28 | * A single wait-queue entry structure: |
---|
.. | .. |
---|
102 | 104 | * lead to sporadic and non-obvious failure. |
---|
103 | 105 | * |
---|
104 | 106 | * Use either while holding wait_queue_head::lock or when used for wakeups |
---|
105 | | - * with an extra smp_mb() like: |
---|
| 107 | + * with an extra smp_mb() like:: |
---|
106 | 108 | * |
---|
107 | 109 | * CPU0 - waker CPU1 - waiter |
---|
108 | 110 | * |
---|
.. | .. |
---|
125 | 127 | static inline int waitqueue_active(struct wait_queue_head *wq_head) |
---|
126 | 128 | { |
---|
127 | 129 | return !list_empty(&wq_head->head); |
---|
| 130 | +} |
---|
| 131 | + |
---|
| 132 | +/** |
---|
| 133 | + * wq_has_single_sleeper - check if there is only one sleeper |
---|
| 134 | + * @wq_head: wait queue head |
---|
| 135 | + * |
---|
| 136 | + * Returns true of wq_head has only one sleeper on the list. |
---|
| 137 | + * |
---|
| 138 | + * Please refer to the comment for waitqueue_active. |
---|
| 139 | + */ |
---|
| 140 | +static inline bool wq_has_single_sleeper(struct wait_queue_head *wq_head) |
---|
| 141 | +{ |
---|
| 142 | + return list_is_singular(&wq_head->head); |
---|
128 | 143 | } |
---|
129 | 144 | |
---|
130 | 145 | /** |
---|
.. | .. |
---|
189 | 204 | void __wake_up_locked_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); |
---|
190 | 205 | void __wake_up_locked_key_bookmark(struct wait_queue_head *wq_head, |
---|
191 | 206 | unsigned int mode, void *key, wait_queue_entry_t *bookmark); |
---|
192 | | -void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, int nr, void *key); |
---|
| 207 | +void __wake_up_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); |
---|
| 208 | +void __wake_up_locked_sync_key(struct wait_queue_head *wq_head, unsigned int mode, void *key); |
---|
193 | 209 | void __wake_up_locked(struct wait_queue_head *wq_head, unsigned int mode, int nr); |
---|
194 | | -void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode, int nr); |
---|
| 210 | +void __wake_up_sync(struct wait_queue_head *wq_head, unsigned int mode); |
---|
195 | 211 | void __wake_up_pollfree(struct wait_queue_head *wq_head); |
---|
196 | 212 | |
---|
197 | 213 | #define wake_up(x) __wake_up(x, TASK_NORMAL, 1, NULL) |
---|
.. | .. |
---|
203 | 219 | #define wake_up_interruptible(x) __wake_up(x, TASK_INTERRUPTIBLE, 1, NULL) |
---|
204 | 220 | #define wake_up_interruptible_nr(x, nr) __wake_up(x, TASK_INTERRUPTIBLE, nr, NULL) |
---|
205 | 221 | #define wake_up_interruptible_all(x) __wake_up(x, TASK_INTERRUPTIBLE, 0, NULL) |
---|
206 | | -#define wake_up_interruptible_sync(x) __wake_up_sync((x), TASK_INTERRUPTIBLE, 1) |
---|
| 222 | +#define wake_up_interruptible_sync(x) __wake_up_sync((x), TASK_INTERRUPTIBLE) |
---|
| 223 | +#define wake_up_sync(x) __wake_up_sync((x), TASK_NORMAL) |
---|
207 | 224 | |
---|
208 | 225 | /* |
---|
209 | 226 | * Wakeup macros to be used to report events to the targets. |
---|
.. | .. |
---|
217 | 234 | #define wake_up_interruptible_poll(x, m) \ |
---|
218 | 235 | __wake_up(x, TASK_INTERRUPTIBLE, 1, poll_to_key(m)) |
---|
219 | 236 | #define wake_up_interruptible_sync_poll(x, m) \ |
---|
220 | | - __wake_up_sync_key((x), TASK_INTERRUPTIBLE, 1, poll_to_key(m)) |
---|
| 237 | + __wake_up_sync_key((x), TASK_INTERRUPTIBLE, poll_to_key(m)) |
---|
| 238 | +#define wake_up_interruptible_sync_poll_locked(x, m) \ |
---|
| 239 | + __wake_up_locked_sync_key((x), TASK_INTERRUPTIBLE, poll_to_key(m)) |
---|
221 | 240 | |
---|
222 | 241 | /** |
---|
223 | 242 | * wake_up_pollfree - signal that a polled waitqueue is going away |
---|
.. | .. |
---|
335 | 354 | |
---|
336 | 355 | #define __wait_event_freezable(wq_head, condition) \ |
---|
337 | 356 | ___wait_event(wq_head, condition, TASK_INTERRUPTIBLE, 0, 0, \ |
---|
338 | | - schedule(); try_to_freeze()) |
---|
| 357 | + freezable_schedule()) |
---|
339 | 358 | |
---|
340 | 359 | /** |
---|
341 | 360 | * wait_event_freezable - sleep (or freeze) until a condition gets true |
---|
.. | .. |
---|
394 | 413 | #define __wait_event_freezable_timeout(wq_head, condition, timeout) \ |
---|
395 | 414 | ___wait_event(wq_head, ___wait_cond_timeout(condition), \ |
---|
396 | 415 | TASK_INTERRUPTIBLE, 0, timeout, \ |
---|
397 | | - __ret = schedule_timeout(__ret); try_to_freeze()) |
---|
| 416 | + __ret = freezable_schedule_timeout(__ret)) |
---|
398 | 417 | |
---|
399 | 418 | /* |
---|
400 | 419 | * like wait_event_timeout() -- except it uses TASK_INTERRUPTIBLE to avoid |
---|
.. | .. |
---|
515 | 534 | int __ret = 0; \ |
---|
516 | 535 | struct hrtimer_sleeper __t; \ |
---|
517 | 536 | \ |
---|
518 | | - hrtimer_init_on_stack(&__t.timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); \ |
---|
519 | | - hrtimer_init_sleeper(&__t, current); \ |
---|
520 | | - if ((timeout) != KTIME_MAX) \ |
---|
521 | | - hrtimer_start_range_ns(&__t.timer, timeout, \ |
---|
522 | | - current->timer_slack_ns, \ |
---|
523 | | - HRTIMER_MODE_REL); \ |
---|
| 537 | + hrtimer_init_sleeper_on_stack(&__t, CLOCK_MONOTONIC, \ |
---|
| 538 | + HRTIMER_MODE_REL); \ |
---|
| 539 | + if ((timeout) != KTIME_MAX) { \ |
---|
| 540 | + hrtimer_set_expires_range_ns(&__t.timer, timeout, \ |
---|
| 541 | + current->timer_slack_ns); \ |
---|
| 542 | + hrtimer_sleeper_start_expires(&__t, HRTIMER_MODE_REL); \ |
---|
| 543 | + } \ |
---|
524 | 544 | \ |
---|
525 | 545 | __ret = ___wait_event(wq_head, condition, state, 0, 0, \ |
---|
526 | 546 | if (!__t.task) { \ |
---|
.. | .. |
---|
615 | 635 | |
---|
616 | 636 | #define __wait_event_freezable_exclusive(wq, condition) \ |
---|
617 | 637 | ___wait_event(wq, condition, TASK_INTERRUPTIBLE, 1, 0, \ |
---|
618 | | - schedule(); try_to_freeze()) |
---|
| 638 | + freezable_schedule()) |
---|
619 | 639 | |
---|
620 | 640 | #define wait_event_freezable_exclusive(wq, condition) \ |
---|
621 | 641 | ({ \ |
---|
.. | .. |
---|
1135 | 1155 | * Waitqueues which are removed from the waitqueue_head at wakeup time |
---|
1136 | 1156 | */ |
---|
1137 | 1157 | void prepare_to_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); |
---|
1138 | | -void prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); |
---|
| 1158 | +bool prepare_to_wait_exclusive(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); |
---|
1139 | 1159 | long prepare_to_wait_event(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry, int state); |
---|
1140 | 1160 | void finish_wait(struct wait_queue_head *wq_head, struct wait_queue_entry *wq_entry); |
---|
1141 | | -long __sched wait_woken(struct wait_queue_entry *wq_entry, unsigned int mode, |
---|
1142 | | - long timeout); |
---|
1143 | | -int __sched woken_wake_function(struct wait_queue_entry *wq_entry, |
---|
1144 | | - unsigned int mode, int sync, void *key); |
---|
1145 | | -int __sched autoremove_wake_function(struct wait_queue_entry *wq_entry, |
---|
1146 | | - unsigned int mode, int sync, void *key); |
---|
| 1161 | +long wait_woken(struct wait_queue_entry *wq_entry, unsigned mode, long timeout); |
---|
| 1162 | +int woken_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); |
---|
| 1163 | +int autoremove_wake_function(struct wait_queue_entry *wq_entry, unsigned mode, int sync, void *key); |
---|
1147 | 1164 | |
---|
1148 | 1165 | #define DEFINE_WAIT_FUNC(name, function) \ |
---|
1149 | 1166 | struct wait_queue_entry name = { \ |
---|
.. | .. |
---|
1162 | 1179 | (wait)->flags = 0; \ |
---|
1163 | 1180 | } while (0) |
---|
1164 | 1181 | |
---|
| 1182 | +bool try_invoke_on_locked_down_task(struct task_struct *p, bool (*func)(struct task_struct *t, void *arg), void *arg); |
---|
| 1183 | + |
---|
1165 | 1184 | #endif /* _LINUX_WAIT_H */ |
---|