Import 2.3.18pre1
[davej-history.git] / include / linux / wait.h
blob86bd0871505256527b63028da4007b806fe87196
1 #ifndef _LINUX_WAIT_H
2 #define _LINUX_WAIT_H
4 #define WNOHANG 0x00000001
5 #define WUNTRACED 0x00000002
7 #define __WCLONE 0x80000000
9 #ifdef __KERNEL__
11 #include <linux/kernel.h>
12 #include <linux/list.h>
13 #include <linux/stddef.h>
14 #include <linux/spinlock.h>
16 #include <asm/page.h>
17 #include <asm/processor.h>
20 * Temporary debugging help until all code is converted to the new
21 * waitqueue usage.
23 #define WAITQUEUE_DEBUG 1
25 #if WAITQUEUE_DEBUG
26 extern int printk(const char *fmt, ...);
27 #define WQ_BUG() do { \
28 printk("wq bug, forcing oops.\n"); \
29 *(int*)0 = 0; \
30 } while (0)
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); \
39 WQ_BUG(); \
40 } \
41 } while (0)
42 #endif
44 struct __wait_queue {
45 unsigned int compiler_warning;
46 struct task_struct * task;
47 struct list_head task_list;
48 #if WAITQUEUE_DEBUG
49 long __magic;
50 long __waker;
51 #endif
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
75 #else
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
87 #endif
89 struct __wait_queue_head {
90 wq_lock_t lock;
91 struct list_head task_list;
92 #if WAITQUEUE_DEBUG
93 long __magic;
94 long __creator;
95 #endif
97 typedef struct __wait_queue_head wait_queue_head_t;
99 #if WAITQUEUE_DEBUG
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
104 #else
105 # define __WAITQUEUE_DEBUG_INIT(name)
106 # define __WAITQUEUE_HEAD_DEBUG_INIT(name)
107 #endif
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)
123 #if WAITQUEUE_DEBUG
124 if (!q)
125 WQ_BUG();
126 #endif
127 q->lock = WAITQUEUE_RW_LOCK_UNLOCKED;
128 INIT_LIST_HEAD(&q->task_list);
129 #if WAITQUEUE_DEBUG
130 q->__magic = (long)&q->__magic;
131 q->__creator = (long)current_text_addr();
132 #endif
135 static inline void init_waitqueue_entry(wait_queue_t *q,
136 struct task_struct *p)
138 #if WAITQUEUE_DEBUG
139 if (!q || !p)
140 WQ_BUG();
141 #endif
142 q->task = p;
143 #if WAITQUEUE_DEBUG
144 q->__magic = (long)&q->__magic;
145 #endif
148 static inline int waitqueue_active(wait_queue_head_t *q)
150 #if WAITQUEUE_DEBUG
151 if (!q)
152 WQ_BUG();
153 CHECK_MAGIC_WQHEAD(q);
154 #endif
156 return !list_empty(&q->task_list);
159 extern inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new)
161 #if WAITQUEUE_DEBUG
162 if (!head || !new)
163 WQ_BUG();
164 CHECK_MAGIC_WQHEAD(head);
165 CHECK_MAGIC(new->__magic);
166 if (!head->task_list.next || !head->task_list.prev)
167 WQ_BUG();
168 #endif
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,
176 wait_queue_t *new)
178 #if WAITQUEUE_DEBUG
179 if (!head || !new)
180 WQ_BUG();
181 CHECK_MAGIC_WQHEAD(head);
182 CHECK_MAGIC(new->__magic);
183 if (!head->task_list.next || !head->task_list.prev)
184 WQ_BUG();
185 #endif
186 list_add(&new->task_list, head->task_list.prev);
189 extern inline void __remove_wait_queue(wait_queue_head_t *head,
190 wait_queue_t *old)
192 #if WAITQUEUE_DEBUG
193 if (!old)
194 WQ_BUG();
195 CHECK_MAGIC(old->__magic);
196 #endif
197 list_del(&old->task_list);
200 #endif /* __KERNEL__ */
202 #endif