1,243 → 1,246 |
#ifndef _LINUX_WAIT_H |
#define _LINUX_WAIT_H |
|
#define WNOHANG 0x00000001 |
#define WUNTRACED 0x00000002 |
|
#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */ |
#define __WALL 0x40000000 /* Wait on all children, regardless of type */ |
#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */ |
|
#ifdef __KERNEL__ |
|
#include <linux/config.h> |
#include <linux/list.h> |
#include <linux/stddef.h> |
#include <linux/spinlock.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); |
extern int default_wake_function(wait_queue_t *wait, unsigned mode, int sync); |
|
struct __wait_queue { |
unsigned int flags; |
#define WQ_FLAG_EXCLUSIVE 0x01 |
struct task_struct * task; |
wait_queue_func_t func; |
struct list_head task_list; |
}; |
|
struct __wait_queue_head { |
spinlock_t lock; |
struct list_head task_list; |
}; |
typedef struct __wait_queue_head wait_queue_head_t; |
|
|
/* |
* Macros for declaration and initialisaton of the datatypes |
*/ |
|
#define __WAITQUEUE_INITIALIZER(name, tsk) { \ |
.task = tsk, \ |
.func = default_wake_function, \ |
.task_list = { NULL, NULL } } |
|
#define DECLARE_WAITQUEUE(name, tsk) \ |
wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) |
|
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ |
.lock = SPIN_LOCK_UNLOCKED, \ |
.task_list = { &(name).task_list, &(name).task_list } } |
|
#define DECLARE_WAIT_QUEUE_HEAD(name) \ |
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) |
|
extern void init_waitqueue_head(wait_queue_head_t *q); |
|
extern void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p); |
|
extern void init_waitqueue_func_entry(wait_queue_t *q, |
wait_queue_func_t func); |
|
extern int waitqueue_active(wait_queue_head_t *q); |
|
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)); |
|
extern void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new); |
|
/* |
* Used for wake-one threads: |
*/ |
static inline void __add_wait_queue_tail(wait_queue_head_t *head, |
wait_queue_t *new) |
{ |
list_add_tail(&new->task_list, &head->task_list); |
} |
|
static inline void __remove_wait_queue(wait_queue_head_t *head, |
wait_queue_t *old) |
{ |
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_all_sync(x) __wake_up_sync((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) |
#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) |
|
#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); |
} |
|
/* |
* 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)); |
void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q, |
wait_queue_t *wait, int state)); |
void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait)); |
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync); |
|
#define DEFINE_WAIT(name) \ |
wait_queue_t name = { \ |
.task = current, \ |
.func = autoremove_wake_function, \ |
.task_list = { .next = &name.task_list, \ |
.prev = &name.task_list, \ |
}, \ |
} |
|
#define init_wait(wait) \ |
do { \ |
wait->task = current; \ |
wait->func = autoremove_wake_function; \ |
INIT_LIST_HEAD(&wait->task_list); \ |
} while (0) |
|
#endif /* __KERNEL__ */ |
|
#endif |
#ifndef _LINUX_WAIT_H |
#define _LINUX_WAIT_H |
|
#define WNOHANG 0x00000001 |
#define WUNTRACED 0x00000002 |
|
#define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */ |
#define __WALL 0x40000000 /* Wait on all children, regardless of type */ |
#define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */ |
|
#ifdef __KERNEL__ |
|
#include <linux/config.h> |
#include <linux/list.h> |
#include <linux/stddef.h> |
#include <linux/spinlock.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); |
extern int default_wake_function(wait_queue_t *wait, unsigned mode, int sync); |
|
struct __wait_queue { |
unsigned int flags; |
#define WQ_FLAG_EXCLUSIVE 0x01 |
struct task_struct * task; |
wait_queue_func_t func; |
struct list_head task_list; |
}; |
|
struct __wait_queue_head { |
spinlock_t lock; |
struct list_head task_list; |
}; |
typedef struct __wait_queue_head wait_queue_head_t; |
|
|
/* |
* Macros for declaration and initialisaton of the datatypes |
*/ |
|
#define __WAITQUEUE_INITIALIZER(name, tsk) { \ |
.task = tsk, \ |
.func = default_wake_function, \ |
.task_list = { NULL, NULL } } |
|
#define DECLARE_WAITQUEUE(name, tsk) \ |
wait_queue_t name = __WAITQUEUE_INITIALIZER(name, tsk) |
|
#define __WAIT_QUEUE_HEAD_INITIALIZER(name) { \ |
.lock = SPIN_LOCK_UNLOCKED, \ |
.task_list = { &(name).task_list, &(name).task_list } } |
|
#define DECLARE_WAIT_QUEUE_HEAD(name) \ |
wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name) |
|
extern void init_waitqueue_head(wait_queue_head_t *q); |
|
extern void init_waitqueue_entry(wait_queue_t *q, struct task_struct *p); |
|
extern void init_waitqueue_func_entry(wait_queue_t *q, |
wait_queue_func_t func); |
|
extern int waitqueue_active(wait_queue_head_t *q); |
|
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)); |
|
extern void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new); |
|
/* |
* Used for wake-one threads: |
*/ |
static inline void __add_wait_queue_tail(wait_queue_head_t *head, |
wait_queue_t *new) |
{ |
list_add_tail(&new->task_list, &head->task_list); |
} |
|
|
extern void free(void *ptr); |
static inline void __remove_wait_queue(wait_queue_head_t *head, |
wait_queue_t *old) |
{ |
free(old->task); //** SHARK |
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_all_sync(x) __wake_up_sync((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) |
#define wake_up_interruptible_sync(x) __wake_up_sync((x),TASK_INTERRUPTIBLE, 1) |
|
#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); |
} |
|
/* |
* 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)); |
void FASTCALL(prepare_to_wait_exclusive(wait_queue_head_t *q, |
wait_queue_t *wait, int state)); |
void FASTCALL(finish_wait(wait_queue_head_t *q, wait_queue_t *wait)); |
int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync); |
|
#define DEFINE_WAIT(name) \ |
wait_queue_t name = { \ |
.task = current, \ |
.func = autoremove_wake_function, \ |
.task_list = { .next = &name.task_list, \ |
.prev = &name.task_list, \ |
}, \ |
} |
|
#define init_wait(wait) \ |
do { \ |
wait->task = current; \ |
wait->func = autoremove_wake_function; \ |
INIT_LIST_HEAD(&wait->task_list); \ |
} while (0) |
|
#endif /* __KERNEL__ */ |
|
#endif |