diff options
| author | Matthew Wilcox <willy@debian.org> | 2002-11-15 18:25:48 -0800 |
|---|---|---|
| committer | Linus Torvalds <torvalds@penguin.transmeta.com> | 2002-11-15 18:25:48 -0800 |
| commit | 2b2cb8a07720d039c74cb33a6dacea1b72db1ee8 (patch) | |
| tree | 38b22786900fae665f87dae5da5f89c5a66852f5 /include/linux/wait.h | |
| parent | 8f57bc89bf2eda1a92af9cde6c7f51ea913a123c (diff) | |
[PATCH] Move wait queue handling from sched.h to wait.h
This patch removes all the wait_queue handling code from sched.h and puts
it in wait.h with the rest of the wait_queue handling code. Note that
sched.h must continue to include wait.h for the wait_queue_head_t embedded
in struct task. However there may be files which only need wait.h now.
Diffstat (limited to 'include/linux/wait.h')
| -rw-r--r-- | include/linux/wait.h | 144 |
1 files changed, 138 insertions, 6 deletions
diff --git a/include/linux/wait.h b/include/linux/wait.h index b6ce459f8792..f05754e8a3ca 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h @@ -10,14 +10,11 @@ #ifdef __KERNEL__ -#include <linux/kernel.h> +#include <linux/config.h> #include <linux/list.h> #include <linux/stddef.h> #include <linux/spinlock.h> -#include <linux/config.h> - -#include <asm/page.h> -#include <asm/processor.h> +#include <asm/system.h> typedef struct __wait_queue wait_queue_t; typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int sync); @@ -83,6 +80,10 @@ static inline int waitqueue_active(wait_queue_head_t *q) return !list_empty(&q->task_list); } +extern void FASTCALL(add_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); +extern void FASTCALL(add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t * wait)); +extern void FASTCALL(remove_wait_queue(wait_queue_head_t *q, wait_queue_t * wait)); + static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) { list_add(&new->task_list, &head->task_list); @@ -103,6 +104,125 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, list_del(&old->task_list); } +extern void FASTCALL(__wake_up(wait_queue_head_t *q, unsigned int mode, int nr)); +extern void FASTCALL(__wake_up_locked(wait_queue_head_t *q, unsigned int mode)); +extern void FASTCALL(__wake_up_sync(wait_queue_head_t *q, unsigned int mode, int nr)); + +#define wake_up(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 1) +#define wake_up_nr(x, nr) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, nr) +#define wake_up_all(x) __wake_up((x),TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE, 0) +#define wake_up_interruptible(x) __wake_up((x),TASK_INTERRUPTIBLE, 1) +#define wake_up_interruptible_nr(x, nr) __wake_up((x),TASK_INTERRUPTIBLE, nr) +#define wake_up_interruptible_all(x) __wake_up((x),TASK_INTERRUPTIBLE, 0) +#define wake_up_locked(x) __wake_up_locked((x), TASK_UNINTERRUPTIBLE | TASK_INTERRUPTIBLE) +#ifdef CONFIG_SMP +#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) +#else +#define wake_up_interruptible_sync(x) __wake_up((x),TASK_INTERRUPTIBLE, 1) +#endif + +#define __wait_event(wq, condition) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_UNINTERRUPTIBLE); \ + if (condition) \ + break; \ + schedule(); \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event(wq, condition) \ +do { \ + if (condition) \ + break; \ + __wait_event(wq, condition); \ +} while (0) + +#define __wait_event_interruptible(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + schedule(); \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible(wq, condition) \ +({ \ + int __ret = 0; \ + if (!(condition)) \ + __wait_event_interruptible(wq, condition, __ret); \ + __ret; \ +}) + +#define __wait_event_interruptible_timeout(wq, condition, ret) \ +do { \ + wait_queue_t __wait; \ + init_waitqueue_entry(&__wait, current); \ + \ + add_wait_queue(&wq, &__wait); \ + for (;;) { \ + set_current_state(TASK_INTERRUPTIBLE); \ + if (condition) \ + break; \ + if (!signal_pending(current)) { \ + ret = schedule_timeout(ret); \ + if (!ret) \ + break; \ + continue; \ + } \ + ret = -ERESTARTSYS; \ + break; \ + } \ + current->state = TASK_RUNNING; \ + remove_wait_queue(&wq, &__wait); \ +} while (0) + +#define wait_event_interruptible_timeout(wq, condition, timeout) \ +({ \ + long __ret = timeout; \ + if (!(condition)) \ + __wait_event_interruptible_timeout(wq, condition, __ret); \ + __ret; \ +}) + +/* + * Must be called with the spinlock in the wait_queue_head_t held. + */ +static inline void add_wait_queue_exclusive_locked(wait_queue_head_t *q, + wait_queue_t * wait) +{ + wait->flags |= WQ_FLAG_EXCLUSIVE; + __add_wait_queue_tail(q, wait); +} + +/* + * Must be called with the spinlock in the wait_queue_head_t held. + */ +static inline void remove_wait_queue_locked(wait_queue_head_t *q, + wait_queue_t * wait) +{ + __remove_wait_queue(q, wait); +} + #define add_wait_queue_cond(q, wait, cond) \ ({ \ unsigned long flags; \ @@ -120,7 +240,19 @@ static inline void __remove_wait_queue(wait_queue_head_t *head, }) /* - * Waitqueue's which are removed from the waitqueue_head at wakeup time + * These are the old interfaces to sleep waiting for an event. + * They are racy. DO NOT use them, use the wait_event* interfaces above. + * We plan to remove these interfaces during 2.7. + */ +extern void FASTCALL(sleep_on(wait_queue_head_t *q)); +extern long FASTCALL(sleep_on_timeout(wait_queue_head_t *q, + signed long timeout)); +extern void FASTCALL(interruptible_sleep_on(wait_queue_head_t *q)); +extern long FASTCALL(interruptible_sleep_on_timeout(wait_queue_head_t *q, + signed long timeout)); + +/* + * Waitqueues which are removed from the waitqueue_head at wakeup time */ void FASTCALL(prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)); |
