00001
00002
00003
00004
00005
00006 #include <linux/init.h>
00007 #include <linux/module.h>
00008 #include <linux/sched.h>
00009 #include <linux/mm.h>
00010 #include <linux/wait.h>
00011 #include <linux/hash.h>
00012
00013 #ifdef DDE_LINUX
00014 #include "local.h"
00015 #endif
00016
00017 void init_waitqueue_head(wait_queue_head_t *q)
00018 {
00019 spin_lock_init(&q->lock);
00020 INIT_LIST_HEAD(&q->task_list);
00021 }
00022
00023 EXPORT_SYMBOL(init_waitqueue_head);
00024
00025 void add_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
00026 {
00027 unsigned long flags;
00028
00029 wait->flags &= ~WQ_FLAG_EXCLUSIVE;
00030 spin_lock_irqsave(&q->lock, flags);
00031 __add_wait_queue(q, wait);
00032 spin_unlock_irqrestore(&q->lock, flags);
00033 }
00034 EXPORT_SYMBOL(add_wait_queue);
00035
00036 void add_wait_queue_exclusive(wait_queue_head_t *q, wait_queue_t *wait)
00037 {
00038 unsigned long flags;
00039
00040 wait->flags |= WQ_FLAG_EXCLUSIVE;
00041 spin_lock_irqsave(&q->lock, flags);
00042 __add_wait_queue_tail(q, wait);
00043 spin_unlock_irqrestore(&q->lock, flags);
00044 }
00045 EXPORT_SYMBOL(add_wait_queue_exclusive);
00046
00047 void remove_wait_queue(wait_queue_head_t *q, wait_queue_t *wait)
00048 {
00049 unsigned long flags;
00050
00051 spin_lock_irqsave(&q->lock, flags);
00052 __remove_wait_queue(q, wait);
00053 spin_unlock_irqrestore(&q->lock, flags);
00054 }
00055 EXPORT_SYMBOL(remove_wait_queue);
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070 void
00071 prepare_to_wait(wait_queue_head_t *q, wait_queue_t *wait, int state)
00072 {
00073 unsigned long flags;
00074
00075 wait->flags &= ~WQ_FLAG_EXCLUSIVE;
00076 spin_lock_irqsave(&q->lock, flags);
00077 if (list_empty(&wait->task_list))
00078 __add_wait_queue(q, wait);
00079 set_current_state(state);
00080 spin_unlock_irqrestore(&q->lock, flags);
00081 }
00082 EXPORT_SYMBOL(prepare_to_wait);
00083
00084 void
00085 prepare_to_wait_exclusive(wait_queue_head_t *q, wait_queue_t *wait, int state)
00086 {
00087 unsigned long flags;
00088
00089 wait->flags |= WQ_FLAG_EXCLUSIVE;
00090 spin_lock_irqsave(&q->lock, flags);
00091 if (list_empty(&wait->task_list))
00092 __add_wait_queue_tail(q, wait);
00093 set_current_state(state);
00094 spin_unlock_irqrestore(&q->lock, flags);
00095 }
00096 EXPORT_SYMBOL(prepare_to_wait_exclusive);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 void finish_wait(wait_queue_head_t *q, wait_queue_t *wait)
00108 {
00109 unsigned long flags;
00110
00111 __set_current_state(TASK_RUNNING);
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125 if (!list_empty_careful(&wait->task_list)) {
00126 spin_lock_irqsave(&q->lock, flags);
00127 list_del_init(&wait->task_list);
00128 spin_unlock_irqrestore(&q->lock, flags);
00129 }
00130 }
00131 EXPORT_SYMBOL(finish_wait);
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151 void abort_exclusive_wait(wait_queue_head_t *q, wait_queue_t *wait,
00152 unsigned int mode, void *key)
00153 {
00154 unsigned long flags;
00155
00156 __set_current_state(TASK_RUNNING);
00157 spin_lock_irqsave(&q->lock, flags);
00158 if (!list_empty(&wait->task_list))
00159 list_del_init(&wait->task_list);
00160 else if (waitqueue_active(q))
00161 __wake_up_common(q, mode, 1, 0, key);
00162 spin_unlock_irqrestore(&q->lock, flags);
00163 }
00164 EXPORT_SYMBOL(abort_exclusive_wait);
00165
00166 int autoremove_wake_function(wait_queue_t *wait, unsigned mode, int sync, void *key)
00167 {
00168 int ret = default_wake_function(wait, mode, sync, key);
00169
00170 if (ret)
00171 list_del_init(&wait->task_list);
00172 return ret;
00173 }
00174 EXPORT_SYMBOL(autoremove_wake_function);
00175
00176 int wake_bit_function(wait_queue_t *wait, unsigned mode, int sync, void *arg)
00177 {
00178 struct wait_bit_key *key = arg;
00179 struct wait_bit_queue *wait_bit
00180 = container_of(wait, struct wait_bit_queue, wait);
00181
00182 if (wait_bit->key.flags != key->flags ||
00183 wait_bit->key.bit_nr != key->bit_nr ||
00184 test_bit(key->bit_nr, key->flags))
00185 return 0;
00186 else
00187 return autoremove_wake_function(wait, mode, sync, key);
00188 }
00189 EXPORT_SYMBOL(wake_bit_function);
00190
00191
00192
00193
00194
00195
00196 int __sched
00197 __wait_on_bit(wait_queue_head_t *wq, struct wait_bit_queue *q,
00198 int (*action)(void *), unsigned mode)
00199 {
00200 int ret = 0;
00201
00202 do {
00203 prepare_to_wait(wq, &q->wait, mode);
00204 if (test_bit(q->key.bit_nr, q->key.flags))
00205 ret = (*action)(q->key.flags);
00206 } while (test_bit(q->key.bit_nr, q->key.flags) && !ret);
00207 finish_wait(wq, &q->wait);
00208 return ret;
00209 }
00210 EXPORT_SYMBOL(__wait_on_bit);
00211
00212 int __sched out_of_line_wait_on_bit(void *word, int bit,
00213 int (*action)(void *), unsigned mode)
00214 {
00215 wait_queue_head_t *wq = bit_waitqueue(word, bit);
00216 DEFINE_WAIT_BIT(wait, word, bit);
00217
00218 return __wait_on_bit(wq, &wait, action, mode);
00219 }
00220 EXPORT_SYMBOL(out_of_line_wait_on_bit);
00221
00222 int __sched
00223 __wait_on_bit_lock(wait_queue_head_t *wq, struct wait_bit_queue *q,
00224 int (*action)(void *), unsigned mode)
00225 {
00226 do {
00227 int ret;
00228
00229 prepare_to_wait_exclusive(wq, &q->wait, mode);
00230 if (!test_bit(q->key.bit_nr, q->key.flags))
00231 continue;
00232 ret = action(q->key.flags);
00233 if (!ret)
00234 continue;
00235 abort_exclusive_wait(wq, &q->wait, mode, &q->key);
00236 return ret;
00237 } while (test_and_set_bit(q->key.bit_nr, q->key.flags));
00238 finish_wait(wq, &q->wait);
00239 return 0;
00240 }
00241 EXPORT_SYMBOL(__wait_on_bit_lock);
00242
00243 int __sched out_of_line_wait_on_bit_lock(void *word, int bit,
00244 int (*action)(void *), unsigned mode)
00245 {
00246 wait_queue_head_t *wq = bit_waitqueue(word, bit);
00247 DEFINE_WAIT_BIT(wait, word, bit);
00248
00249 return __wait_on_bit_lock(wq, &wait, action, mode);
00250 }
00251 EXPORT_SYMBOL(out_of_line_wait_on_bit_lock);
00252
00253 void __wake_up_bit(wait_queue_head_t *wq, void *word, int bit)
00254 {
00255 #ifndef DDE_LINUX
00256 struct wait_bit_key key = __WAIT_BIT_KEY_INITIALIZER(word, bit);
00257 if (waitqueue_active(wq))
00258 __wake_up(wq, TASK_NORMAL, 1, &key);
00259 #else
00260 WARN_UNIMPL;
00261 #endif
00262 }
00263 EXPORT_SYMBOL(__wake_up_bit);
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282 void wake_up_bit(void *word, int bit)
00283 {
00284 __wake_up_bit(bit_waitqueue(word, bit), word, bit);
00285 }
00286 EXPORT_SYMBOL(wake_up_bit);
00287
00288 wait_queue_head_t *bit_waitqueue(void *word, int bit)
00289 {
00290 #ifndef DDE_LINUX
00291 const int shift = BITS_PER_LONG == 32 ? 5 : 6;
00292 const struct zone *zone = page_zone(virt_to_page(word));
00293 unsigned long val = (unsigned long)word << shift | bit;
00294
00295 return &zone->wait_table[hash_long(val, zone->wait_table_bits)];
00296 #else
00297 WARN_UNIMPL;
00298 return NULL;
00299 #endif
00300 }
00301 EXPORT_SYMBOL(bit_waitqueue);