4 #define WNOHANG 0x00000001
5 #define WUNTRACED 0x00000002
7 #define __WCLONE 0x80000000
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/stddef.h>
14 #include <linux/spinlock.h>
17 #include <asm/processor.h>
20 * Temporary debugging help until all code is converted to the new
23 #define WAITQUEUE_DEBUG 1
26 extern int printk(const char *fmt
, ...);
27 #define WQ_BUG() do { \
28 printk("wq bug, forcing oops.\n"); \
32 #define CHECK_MAGIC(x) if (x != (long)&(x)) \
33 { printk("bad magic %lx (should be %lx), ", (long)x, (long)&(x)); WQ_BUG(); }
35 #define CHECK_MAGIC_WQHEAD(x) do { \
36 if (x->__magic != (long)&(x->__magic)) { \
37 printk("bad magic %lx (should be %lx, creator %lx), ", \
38 x->__magic, (long)&(x->__magic), x->__creator); \
45 unsigned int compiler_warning
;
46 struct task_struct
* task
;
47 struct list_head task_list
;
53 typedef struct __wait_queue wait_queue_t
;
56 * 'dual' spinlock architecture. Can be switched between spinlock_t and
57 * rwlock_t locks via changing this define. Since waitqueues are quite
58 * decoupled in the new architecture, lightweight 'simple' spinlocks give
59 * us slightly better latencies and smaller waitqueue structure size.
61 #define USE_RW_WAIT_QUEUE_SPINLOCK 0
63 #if USE_RW_WAIT_QUEUE_SPINLOCK
64 # define wq_lock_t rwlock_t
65 # define WAITQUEUE_RW_LOCK_UNLOCKED RW_LOCK_UNLOCKED
67 # define wq_read_lock read_lock
68 # define wq_read_lock_irqsave read_lock_irqsave
69 # define wq_read_unlock_irqrestore read_unlock_irqrestore
70 # define wq_read_unlock read_unlock
71 # define wq_write_lock_irq write_lock_irq
72 # define wq_write_lock_irqsave write_lock_irqsave
73 # define wq_write_unlock_irqrestore write_unlock_irqrestore
74 # define wq_write_unlock write_unlock
76 # define wq_lock_t spinlock_t
77 # define WAITQUEUE_RW_LOCK_UNLOCKED SPIN_LOCK_UNLOCKED
79 # define wq_read_lock spin_lock
80 # define wq_read_lock_irqsave spin_lock_irqsave
81 # define wq_read_unlock spin_unlock
82 # define wq_read_unlock_irqrestore spin_unlock_irqrestore
83 # define wq_write_lock_irq spin_lock_irq
84 # define wq_write_lock_irqsave spin_lock_irqsave
85 # define wq_write_unlock_irqrestore spin_unlock_irqrestore
86 # define wq_write_unlock spin_unlock
89 struct __wait_queue_head
{
91 struct list_head task_list
;
97 typedef struct __wait_queue_head wait_queue_head_t
;
100 # define __WAITQUEUE_DEBUG_INIT(name) \
101 , (long)&(name).__magic, 0
102 # define __WAITQUEUE_HEAD_DEBUG_INIT(name) \
103 , (long)&(name).__magic, (long)&(name).__magic
105 # define __WAITQUEUE_DEBUG_INIT(name)
106 # define __WAITQUEUE_HEAD_DEBUG_INIT(name)
109 #define __WAITQUEUE_INITIALIZER(name,task) \
110 { 0x1234567, task, { NULL, NULL } __WAITQUEUE_DEBUG_INIT(name)}
111 #define DECLARE_WAITQUEUE(name,task) \
112 wait_queue_t name = __WAITQUEUE_INITIALIZER(name,task)
114 #define __WAIT_QUEUE_HEAD_INITIALIZER(name) \
115 { WAITQUEUE_RW_LOCK_UNLOCKED, { &(name).task_list, &(name).task_list } \
116 __WAITQUEUE_HEAD_DEBUG_INIT(name)}
118 #define DECLARE_WAIT_QUEUE_HEAD(name) \
119 wait_queue_head_t name = __WAIT_QUEUE_HEAD_INITIALIZER(name)
121 static inline void init_waitqueue_head(wait_queue_head_t
*q
)
127 q
->lock
= WAITQUEUE_RW_LOCK_UNLOCKED
;
128 INIT_LIST_HEAD(&q
->task_list
);
130 q
->__magic
= (long)&q
->__magic
;
131 q
->__creator
= (long)current_text_addr();
135 static inline void init_waitqueue_entry(wait_queue_t
*q
,
136 struct task_struct
*p
)
144 q
->__magic
= (long)&q
->__magic
;
148 static inline int waitqueue_active(wait_queue_head_t
*q
)
153 CHECK_MAGIC_WQHEAD(q
);
156 return !list_empty(&q
->task_list
);
159 extern inline void __add_wait_queue(wait_queue_head_t
*head
, wait_queue_t
*new)
164 CHECK_MAGIC_WQHEAD(head
);
165 CHECK_MAGIC(new->__magic
);
166 if (!head
->task_list
.next
|| !head
->task_list
.prev
)
169 list_add(&new->task_list
, &head
->task_list
);
173 * Used for wake-one threads:
175 extern inline void __add_wait_queue_tail(wait_queue_head_t
*head
,
181 CHECK_MAGIC_WQHEAD(head
);
182 CHECK_MAGIC(new->__magic
);
183 if (!head
->task_list
.next
|| !head
->task_list
.prev
)
186 list_add(&new->task_list
, head
->task_list
.prev
);
189 extern inline void __remove_wait_queue(wait_queue_head_t
*head
,
195 CHECK_MAGIC(old
->__magic
);
197 list_del(&old
->task_list
);
200 #endif /* __KERNEL__ */