Rev 3297 | Rev 3480 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
2967 | Serge | 1 | #ifndef _LINUX_WAIT_H |
2 | #define _LINUX_WAIT_H |
||
3 | |||
3297 | Serge | 4 | #include |
3192 | Serge | 5 | #include |
6 | |||
2967 | Serge | 7 | typedef struct __wait_queue wait_queue_t; |
3391 | Serge | 8 | typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key); |
9 | |||
2967 | Serge | 10 | typedef struct __wait_queue_head wait_queue_head_t; |
11 | |||
12 | struct __wait_queue |
||
13 | { |
||
3391 | Serge | 14 | wait_queue_func_t func; |
2967 | Serge | 15 | struct list_head task_list; |
16 | evhandle_t evnt; |
||
17 | }; |
||
18 | |||
19 | struct __wait_queue_head |
||
20 | { |
||
21 | spinlock_t lock; |
||
22 | struct list_head task_list; |
||
23 | }; |
||
24 | |||
25 | static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) |
||
26 | { |
||
27 | list_add(&new->task_list, &head->task_list); |
||
28 | } |
||
29 | |||
30 | |||
31 | #define __wait_event(wq, condition) \ |
||
32 | do { \ |
||
33 | DEFINE_WAIT(__wait); \ |
||
34 | \ |
||
35 | for (;;) { \ |
||
36 | prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ |
||
37 | if (condition) \ |
||
38 | break; \ |
||
39 | schedule(); \ |
||
40 | } \ |
||
41 | finish_wait(&wq, &__wait); \ |
||
42 | } while (0) |
||
43 | |||
44 | |||
3031 | serge | 45 | |
46 | #define wait_event_timeout(wq, condition, timeout) \ |
||
47 | ({ \ |
||
48 | long __ret = timeout; \ |
||
49 | do{ \ |
||
50 | wait_queue_t __wait = { \ |
||
51 | .task_list = LIST_HEAD_INIT(__wait.task_list), \ |
||
52 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
53 | }; \ |
||
3297 | Serge | 54 | unsigned long flags; \ |
3031 | serge | 55 | \ |
56 | spin_lock_irqsave(&wq.lock, flags); \ |
||
57 | if (list_empty(&__wait.task_list)) \ |
||
58 | __add_wait_queue(&wq, &__wait); \ |
||
59 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
60 | \ |
||
61 | for(;;){ \ |
||
62 | if (condition) \ |
||
63 | break; \ |
||
3391 | Serge | 64 | WaitEventTimeout(__wait.evnt, timeout); \ |
3031 | serge | 65 | }; \ |
3297 | Serge | 66 | if (!list_empty(&__wait.task_list)) { \ |
3031 | serge | 67 | spin_lock_irqsave(&wq.lock, flags); \ |
68 | list_del_init(&__wait.task_list); \ |
||
69 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
70 | }; \ |
||
71 | DestroyEvent(__wait.evnt); \ |
||
72 | } while (0); \ |
||
73 | __ret; \ |
||
74 | }) |
||
75 | |||
3192 | Serge | 76 | #define wait_event_interruptible_timeout(wq, condition, timeout) \ |
77 | wait_event_timeout(wq, condition, timeout) |
||
3031 | serge | 78 | |
79 | |||
2967 | Serge | 80 | #define wait_event(wq, condition) \ |
81 | do{ \ |
||
82 | wait_queue_t __wait = { \ |
||
83 | .task_list = LIST_HEAD_INIT(__wait.task_list), \ |
||
84 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
85 | }; \ |
||
3297 | Serge | 86 | unsigned long flags; \ |
2967 | Serge | 87 | \ |
88 | spin_lock_irqsave(&wq.lock, flags); \ |
||
89 | if (list_empty(&__wait.task_list)) \ |
||
90 | __add_wait_queue(&wq, &__wait); \ |
||
91 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
92 | \ |
||
93 | for(;;){ \ |
||
94 | if (condition) \ |
||
95 | break; \ |
||
96 | WaitEvent(__wait.evnt); \ |
||
97 | }; \ |
||
98 | if (!list_empty_careful(&__wait.task_list)) { \ |
||
99 | spin_lock_irqsave(&wq.lock, flags); \ |
||
100 | list_del_init(&__wait.task_list); \ |
||
101 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
102 | }; \ |
||
103 | DestroyEvent(__wait.evnt); \ |
||
104 | } while (0) |
||
105 | |||
106 | |||
3031 | serge | 107 | |
108 | |||
2967 | Serge | 109 | static inline |
110 | void wake_up_all(wait_queue_head_t *q) |
||
111 | { |
||
112 | wait_queue_t *curr; |
||
113 | unsigned long flags; |
||
114 | |||
115 | spin_lock_irqsave(&q->lock, flags); |
||
116 | list_for_each_entry(curr, &q->task_list, task_list) |
||
117 | { |
||
3297 | Serge | 118 | // printf("raise event \n"); |
119 | |||
2967 | Serge | 120 | kevent_t event; |
121 | event.code = -1; |
||
122 | RaiseEvent(curr->evnt, 0, &event); |
||
123 | } |
||
124 | spin_unlock_irqrestore(&q->lock, flags); |
||
125 | } |
||
126 | |||
127 | |||
128 | static inline void |
||
129 | init_waitqueue_head(wait_queue_head_t *q) |
||
130 | { |
||
131 | spin_lock_init(&q->lock); |
||
132 | INIT_LIST_HEAD(&q->task_list); |
||
133 | }; |
||
134 | |||
135 | |||
136 | /* |
||
137 | * Workqueue flags and constants. For details, please refer to |
||
138 | * Documentation/workqueue.txt. |
||
139 | */ |
||
140 | enum { |
||
141 | WQ_NON_REENTRANT = 1 << 0, /* guarantee non-reentrance */ |
||
142 | WQ_UNBOUND = 1 << 1, /* not bound to any cpu */ |
||
143 | WQ_FREEZABLE = 1 << 2, /* freeze during suspend */ |
||
144 | WQ_MEM_RECLAIM = 1 << 3, /* may be used for memory reclaim */ |
||
145 | WQ_HIGHPRI = 1 << 4, /* high priority */ |
||
146 | WQ_CPU_INTENSIVE = 1 << 5, /* cpu instensive workqueue */ |
||
147 | |||
148 | WQ_DRAINING = 1 << 6, /* internal: workqueue is draining */ |
||
149 | WQ_RESCUER = 1 << 7, /* internal: workqueue has rescuer */ |
||
150 | |||
151 | WQ_MAX_ACTIVE = 512, /* I like 512, better ideas? */ |
||
152 | WQ_MAX_UNBOUND_PER_CPU = 4, /* 4 * #cpus for unbound wq */ |
||
153 | WQ_DFL_ACTIVE = WQ_MAX_ACTIVE / 2, |
||
154 | }; |
||
155 | |||
156 | struct work_struct; |
||
157 | |||
158 | struct workqueue_struct { |
||
159 | spinlock_t lock; |
||
160 | struct list_head worklist; |
||
161 | }; |
||
162 | |||
163 | typedef void (*work_func_t)(struct work_struct *work); |
||
164 | |||
165 | struct work_struct { |
||
166 | struct list_head entry; |
||
167 | struct workqueue_struct *data; |
||
168 | work_func_t func; |
||
169 | }; |
||
170 | |||
171 | struct delayed_work { |
||
172 | struct work_struct work; |
||
173 | }; |
||
174 | |||
175 | struct workqueue_struct *alloc_workqueue_key(const char *fmt, |
||
176 | unsigned int flags, int max_active); |
||
177 | |||
3031 | serge | 178 | |
179 | #define alloc_ordered_workqueue(fmt, flags, args...) \ |
||
180 | alloc_workqueue(fmt, WQ_UNBOUND | (flags), 1, ##args) |
||
181 | |||
2967 | Serge | 182 | int queue_delayed_work(struct workqueue_struct *wq, |
183 | struct delayed_work *dwork, unsigned long delay); |
||
184 | |||
185 | #define INIT_DELAYED_WORK(_work, _func) \ |
||
186 | do { \ |
||
187 | INIT_LIST_HEAD(&(_work)->work.entry); \ |
||
188 | (_work)->work.func = _func; \ |
||
189 | } while (0) |
||
190 | |||
3031 | serge | 191 | |
192 | struct completion { |
||
193 | unsigned int done; |
||
194 | wait_queue_head_t wait; |
||
195 | }; |
||
196 | |||
3391 | Serge | 197 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
3031 | serge | 198 | |
3391 | Serge | 199 | |
200 | #define DEFINE_WAIT_FUNC(name, function) \ |
||
201 | wait_queue_t name = { \ |
||
202 | .func = function, \ |
||
203 | .task_list = LIST_HEAD_INIT((name).task_list), \ |
||
204 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
205 | } |
||
206 | |||
207 | #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function) |
||
208 | |||
209 | |||
2967 | Serge | 210 | #endif><>><>><>><>><>><>><>><> |
211 |