Rev 3480 | Rev 4292 | 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 | |||
3482 | Serge | 30 | /* |
2967 | Serge | 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 | |||
3482 | Serge | 44 | */ |
2967 | Serge | 45 | |
3031 | serge | 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 | |||
3031 | serge | 136 | struct completion { |
137 | unsigned int done; |
||
138 | wait_queue_head_t wait; |
||
139 | }; |
||
140 | |||
3391 | Serge | 141 | int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key); |
3031 | serge | 142 | |
3391 | Serge | 143 | |
144 | #define DEFINE_WAIT_FUNC(name, function) \ |
||
145 | wait_queue_t name = { \ |
||
146 | .func = function, \ |
||
147 | .task_list = LIST_HEAD_INIT((name).task_list), \ |
||
148 | .evnt = CreateEvent(NULL, MANUAL_DESTROY), \ |
||
149 | } |
||
150 | |||
151 | #define DEFINE_WAIT(name) DEFINE_WAIT_FUNC(name, autoremove_wake_function) |
||
152 | |||
153 | |||
2967 | Serge | 154 | #endif |
155 |