Rev 4292 | Rev 5270 | 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 | |||
4292 | Serge | 4 | |
3297 | Serge | 5 | #include |
3192 | Serge | 6 | #include |
7 | |||
2967 | Serge | 8 | typedef struct __wait_queue wait_queue_t; |
3391 | Serge | 9 | typedef int (*wait_queue_func_t)(wait_queue_t *wait, unsigned mode, int flags, void *key); |
4292 | Serge | 10 | int default_wake_function(wait_queue_t *wait, unsigned mode, int flags, void *key); |
3391 | Serge | 11 | |
2967 | Serge | 12 | typedef struct __wait_queue_head wait_queue_head_t; |
13 | |||
14 | struct __wait_queue |
||
15 | { |
||
3391 | Serge | 16 | wait_queue_func_t func; |
2967 | Serge | 17 | struct list_head task_list; |
18 | evhandle_t evnt; |
||
19 | }; |
||
20 | |||
21 | struct __wait_queue_head |
||
22 | { |
||
23 | spinlock_t lock; |
||
24 | struct list_head task_list; |
||
25 | }; |
||
4292 | Serge | 26 | static inline int waitqueue_active(wait_queue_head_t *q) |
27 | { |
||
28 | return !list_empty(&q->task_list); |
||
29 | } |
||
2967 | Serge | 30 | |
31 | static inline void __add_wait_queue(wait_queue_head_t *head, wait_queue_t *new) |
||
32 | { |
||
33 | list_add(&new->task_list, &head->task_list); |
||
34 | } |
||
35 | |||
3482 | Serge | 36 | /* |
2967 | Serge | 37 | #define __wait_event(wq, condition) \ |
38 | do { \ |
||
39 | DEFINE_WAIT(__wait); \ |
||
40 | \ |
||
41 | for (;;) { \ |
||
42 | prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); \ |
||
43 | if (condition) \ |
||
44 | break; \ |
||
45 | schedule(); \ |
||
46 | } \ |
||
47 | finish_wait(&wq, &__wait); \ |
||
48 | } while (0) |
||
49 | |||
3482 | Serge | 50 | */ |
2967 | Serge | 51 | |
3031 | serge | 52 | #define wait_event_timeout(wq, condition, timeout) \ |
53 | ({ \ |
||
54 | long __ret = timeout; \ |
||
55 | do{ \ |
||
56 | wait_queue_t __wait = { \ |
||
57 | .task_list = LIST_HEAD_INIT(__wait.task_list), \ |
||
58 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
59 | }; \ |
||
3297 | Serge | 60 | unsigned long flags; \ |
3031 | serge | 61 | \ |
62 | spin_lock_irqsave(&wq.lock, flags); \ |
||
63 | if (list_empty(&__wait.task_list)) \ |
||
64 | __add_wait_queue(&wq, &__wait); \ |
||
65 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
66 | \ |
||
67 | for(;;){ \ |
||
68 | if (condition) \ |
||
69 | break; \ |
||
3391 | Serge | 70 | WaitEventTimeout(__wait.evnt, timeout); \ |
3031 | serge | 71 | }; \ |
3297 | Serge | 72 | if (!list_empty(&__wait.task_list)) { \ |
3031 | serge | 73 | spin_lock_irqsave(&wq.lock, flags); \ |
74 | list_del_init(&__wait.task_list); \ |
||
75 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
76 | }; \ |
||
77 | DestroyEvent(__wait.evnt); \ |
||
78 | } while (0); \ |
||
79 | __ret; \ |
||
80 | }) |
||
81 | |||
3192 | Serge | 82 | #define wait_event_interruptible_timeout(wq, condition, timeout) \ |
83 | wait_event_timeout(wq, condition, timeout) |
||
3031 | serge | 84 | |
85 | |||
2967 | Serge | 86 | #define wait_event(wq, condition) \ |
5056 | serge | 87 | do{ \ |
2967 | Serge | 88 | wait_queue_t __wait = { \ |
89 | .task_list = LIST_HEAD_INIT(__wait.task_list), \ |
||
90 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
91 | }; \ |
||
3297 | Serge | 92 | unsigned long flags; \ |
2967 | Serge | 93 | \ |
94 | spin_lock_irqsave(&wq.lock, flags); \ |
||
95 | if (list_empty(&__wait.task_list)) \ |
||
96 | __add_wait_queue(&wq, &__wait); \ |
||
97 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
98 | \ |
||
99 | for(;;){ \ |
||
100 | if (condition) \ |
||
101 | break; \ |
||
102 | WaitEvent(__wait.evnt); \ |
||
103 | }; \ |
||
104 | if (!list_empty_careful(&__wait.task_list)) { \ |
||
105 | spin_lock_irqsave(&wq.lock, flags); \ |
||
106 | list_del_init(&__wait.task_list); \ |
||
107 | spin_unlock_irqrestore(&wq.lock, flags); \ |
||
108 | }; \ |
||
109 | DestroyEvent(__wait.evnt); \ |
||
110 | } while (0) |
||
111 | |||
5056 | serge | 112 | #define wait_event_interruptible(wq, condition) \ |
113 | ({ \ |
||
114 | int __ret = 0; \ |
||
115 | if (!(condition)) \ |
||
116 | wait_event(wq, condition); \ |
||
117 | __ret; \ |
||
118 | }) |
||
2967 | Serge | 119 | |
3031 | serge | 120 | |
2967 | Serge | 121 | static inline |
122 | void wake_up_all(wait_queue_head_t *q) |
||
123 | { |
||
124 | wait_queue_t *curr; |
||
125 | unsigned long flags; |
||
126 | |||
127 | spin_lock_irqsave(&q->lock, flags); |
||
128 | list_for_each_entry(curr, &q->task_list, task_list) |
||
129 | { |
||
3297 | Serge | 130 | // printf("raise event \n"); |
131 | |||
2967 | Serge | 132 | kevent_t event; |
133 | event.code = -1; |
||
134 | RaiseEvent(curr->evnt, 0, &event); |
||
135 | } |
||
136 | spin_unlock_irqrestore(&q->lock, flags); |
||
137 | } |
||
138 | |||
139 | |||
140 | static inline void |
||
141 | init_waitqueue_head(wait_queue_head_t *q) |
||
142 | { |
||
143 | spin_lock_init(&q->lock); |
||
144 | INIT_LIST_HEAD(&q->task_list); |
||
145 | }; |
||
146 | |||
147 | |||
3031 | serge | 148 | struct completion { |
149 | unsigned int done; |
||
150 | wait_queue_head_t wait; |
||
151 | }; |
||
152 | |||
3391 | Serge | 153 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
3031 | serge | 154 | |
3391 | Serge | 155 | |
156 | #define DEFINE_WAIT_FUNC(name, function) \ |
||
157 | wait_queue_t name = { \ |
||
158 | .func = function, \ |
||
159 | .task_list = LIST_HEAD_INIT((name).task_list), \ |
||
160 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
161 | } |
||
162 | |||
163 | #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function) |
||
164 | |||
165 | |||
2967 | Serge | 166 | #endif |
167 |