diff options
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/wait.h | 149 |
1 files changed, 149 insertions, 0 deletions
diff --git a/include/linux/wait.h b/include/linux/wait.h index a48e16b77d5e..fc3c040e5e3a 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -362,6 +362,155 @@ do { \ __ret; \ }) + +#define __wait_event_interruptible_locked(wq, condition, exclusive, irq) \ +({ \ + int __ret = 0; \ + DEFINE_WAIT(__wait); \ + if (exclusive) \ + __wait.flags |= WQ_FLAG_EXCLUSIVE; \ + do { \ + if (likely(list_empty(&__wait.task_list))) \ + __add_wait_queue_tail(&(wq), &__wait); \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (signal_pending(current)) { \ + __ret = -ERESTARTSYS; \ + break; \ + } \ + if (irq) \ + spin_unlock_irq(&(wq).lock); \ + else \ + spin_unlock(&(wq).lock); \ + schedule(); \ + if (irq) \ + spin_lock_irq(&(wq).lock); \ + else \ + spin_lock(&(wq).lock); \ + } while (!(condition)); \ + __remove_wait_queue(&(wq), &__wait); \ + __set_current_state(TASK_RUNNING); \ + __ret; \ +}) + + +/** + * wait_event_interruptible_locked - sleep until a condition gets true + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * It must be called with wq.lock being held. This spinlock is + * unlocked while sleeping but @condition testing is done while lock + * is held and when this macro exits the lock is held. + * + * The lock is locked/unlocked using spin_lock()/spin_unlock() + * functions which must match the way they are locked/unlocked outside + * of this macro. + * + * wake_up_locked() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function will return -ERESTARTSYS if it was interrupted by a + * signal and 0 if @condition evaluated to true. + */ +#define wait_event_interruptible_locked(wq, condition) \ + ((condition) \ + ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 0)) + +/** + * wait_event_interruptible_locked_irq - sleep until a condition gets true + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * It must be called with wq.lock being held. This spinlock is + * unlocked while sleeping but @condition testing is done while lock + * is held and when this macro exits the lock is held. + * + * The lock is locked/unlocked using spin_lock_irq()/spin_unlock_irq() + * functions which must match the way they are locked/unlocked outside + * of this macro. + * + * wake_up_locked() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function will return -ERESTARTSYS if it was interrupted by a + * signal and 0 if @condition evaluated to true. + */ +#define wait_event_interruptible_locked_irq(wq, condition) \ + ((condition) \ + ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 1)) + +/** + * wait_event_interruptible_exclusive_locked - sleep exclusively until a condition gets true + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * It must be called with wq.lock being held. This spinlock is + * unlocked while sleeping but @condition testing is done while lock + * is held and when this macro exits the lock is held. + * + * The lock is locked/unlocked using spin_lock()/spin_unlock() + * functions which must match the way they are locked/unlocked outside + * of this macro. + * + * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag + * set thus when other process waits process on the list if this + * process is awaken further processes are not considered. + * + * wake_up_locked() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function will return -ERESTARTSYS if it was interrupted by a + * signal and 0 if @condition evaluated to true. + */ +#define wait_event_interruptible_exclusive_locked(wq, condition) \ + ((condition) \ + ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 0)) + +/** + * wait_event_interruptible_exclusive_locked_irq - sleep until a condition gets true + * @wq: the waitqueue to wait on + * @condition: a C expression for the event to wait for + * + * The process is put to sleep (TASK_INTERRUPTIBLE) until the + * @condition evaluates to true or a signal is received. + * The @condition is checked each time the waitqueue @wq is woken up. + * + * It must be called with wq.lock being held. This spinlock is + * unlocked while sleeping but @condition testing is done while lock + * is held and when this macro exits the lock is held. + * + * The lock is locked/unlocked using spin_lock_irq()/spin_unlock_irq() + * functions which must match the way they are locked/unlocked outside + * of this macro. + * + * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag + * set thus when other process waits process on the list if this + * process is awaken further processes are not considered. + * + * wake_up_locked() has to be called after changing any variable that could + * change the result of the wait condition. + * + * The function will return -ERESTARTSYS if it was interrupted by a + * signal and 0 if @condition evaluated to true. + */ +#define wait_event_interruptible_exclusive_locked_irq(wq, condition) \ + ((condition) \ + ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 1)) + + + #define __wait_event_killable(wq, condition, ret) \ do { \ DEFINE_WAIT(__wait); \ |