4 #define WNOHANG 0x00000001
5 #define WUNTRACED 0x00000002
7 #define __WNOTHREAD 0x20000000 /* Don't wait on children of other threads in this group */
8 #define __WALL 0x40000000 /* Wait on all children, regardless of type */
9 #define __WCLONE 0x80000000 /* Wait only on non-SIGCHLD children */
13 #include <linux/kernel.h>
14 #include <linux/list.h>
15 #include <linux/stddef.h>
16 #include <linux/spinlock.h>
19 #include <asm/processor.h>
22 * Temporary debugging help until all code is converted to the new
25 #define WAITQUEUE_DEBUG 0
28 extern int printk(const char *fmt
, ...);
29 #define WQ_BUG() do { \
30 printk("wq bug, forcing oops.\n"); \
34 #define CHECK_MAGIC(x) if (x != (long)&(x)) \
35 { printk("bad magic %lx (should be %lx), ", (long)x, (long)&(x)); WQ_BUG(); }
37 #define CHECK_MAGIC_WQHEAD(x) do { \
38 if (x->__magic != (long)&(x->__magic)) { \
39 printk("bad magic %lx (should be %lx, creator %lx), ", \
40 x->__magic, (long)&(x->__magic), x->__creator); \
48 #define WQ_FLAG_EXCLUSIVE 0x01
49 struct task_struct
* task
;
50 struct list_head task_list
;
56 typedef struct __wait_queue wait_queue_t
;
59 * 'dual' spinlock architecture. Can be switched between spinlock_t and
60 * rwlock_t locks via changing this define. Since waitqueues are quite
61 * decoupled in the new architecture, lightweight 'simple' spinlocks give
62 * us slightly better latencies and smaller waitqueue structure size.
64 #define USE_RW_WAIT_QUEUE_SPINLOCK 0
66 #if USE_RW_WAIT_QUEUE_SPINLOCK
67 # define wq_lock_t rwlock_t
68 # define WAITQUEUE_RW_LOCK_UNLOCKED RW_LOCK_UNLOCKED
70 # define wq_read_lock read_lock
71 # define wq_read_lock_irqsave read_lock_irqsave
72 # define wq_read_unlock_irqrestore read_unlock_irqrestore
73 # define wq_read_unlock read_unlock
74 # define wq_write_lock_irq write_lock_irq
75 # define wq_write_lock_irqsave write_lock_irqsave
76 # define wq_write_unlock_irqrestore write_unlock_irqrestore
77 # define wq_write_unlock write_unlock
79 # define wq_lock_t spinlock_t
80 # define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
82 # define wq_read_lock spin_lock
83 # define wq_read_lock_irqsave spin_lock_irqsave
84 # define wq_read_unlock spin_unlock
85 # define wq_read_unlock_irqrestore spin_unlock_irqrestore
86 # define wq_write_lock_irq spin_lock_irq
87 # define wq_write_lock_irqsave spin_lock_irqsave
88 # define wq_write_unlock_irqrestore spin_unlock_irqrestore
89 # define wq_write_unlock spin_unlock
92 struct __wait_queue_head
{
94 struct list_head task_list
;
100 typedef struct __wait_queue_head wait_queue_head_t
;
103 # define __WAITQUEUE_DEBUG_INIT(name) \
104 , (long)&(name).__magic, 0
105 # define __WAITQUEUE_HEAD_DEBUG_INIT(name) \
106 , (long)&(name).__magic, (long)&(name).__magic
108 # define __WAITQUEUE_DEBUG_INIT(name)
109 # define __WAITQUEUE_HEAD_DEBUG_INIT(name)
112 #define __WAITQUEUE_INITIALIZER(name,task) \
113 { 0x0, task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)}
114 #define DECLARE_WAITQUEUE(name,task) \
115 wait_queue_t name = __WAITQUEUE_INITIALIZER(name,task)
117 #define __WAIT_QUEUE_HEAD_INITIALIZER(name) \
118 { WAITQUEUE_RW_LOCK_UNLOCKED, { &(name).task_list, &(name).task_list } \
119 __WAITQUEUE_HEAD_DEBUG_INIT(name)}
121 #define DECLARE_WAIT_QUEUE_HEAD(name) \
122 wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
124 static inline void init_waitqueue_head(wait_queue_head_t
*q
)
130 q
->lock
= WAITQUEUE_RW_LOCK_UNLOCKED
;
131 INIT_LIST_HEAD(&q
->task_list
);
133 q
->__magic
= (long)&q
->__magic
;
134 q
->__creator
= (long)current_text_addr();
138 static inline void init_waitqueue_entry(wait_queue_t
*q
,
139 struct task_struct
*p
)
148 q
->__magic
= (long)&q
->__magic
;
152 static inline int waitqueue_active(wait_queue_head_t
*q
)
157 CHECK_MAGIC_WQHEAD(q
);
160 return !list_empty(&q
->task_list
);
163 static inline void __add_wait_queue(wait_queue_head_t
*head
, wait_queue_t
*new)
168 CHECK_MAGIC_WQHEAD(head
);
169 CHECK_MAGIC(new->__magic
);
170 if (!head
->task_list
.next
|| !head
->task_list
.prev
)
173 list_add(&new->task_list
, &head
->task_list
);
177 * Used for wake-one threads:
179 static inline void __add_wait_queue_tail(wait_queue_head_t
*head
,
185 CHECK_MAGIC_WQHEAD(head
);
186 CHECK_MAGIC(new->__magic
);
187 if (!head
->task_list
.next
|| !head
->task_list
.prev
)
190 list_add_tail(&new->task_list
, &head
->task_list
);
193 static inline void __remove_wait_queue(wait_queue_head_t
*head
,
199 CHECK_MAGIC(old
->__magic
);
201 list_del(&old
->task_list
);
204 #endif /* __KERNEL__ */