diff options
-rw-r--r-- | include/linux/wait.h | 149 | ||||
-rw-r--r-- | kernel/sched.c | 1 |
2 files changed, 150 insertions, 0 deletions
diff --git a/include/linux/wait.h b/include/linux/wait.h index a48e16b77d5e..fc3c040e5e3a 100644 --- a/include/linux/wait.h +++ b/include/linux/wait.h | |||
@@ -362,6 +362,155 @@ do { \ | |||
362 | __ret; \ | 362 | __ret; \ |
363 | }) | 363 | }) |
364 | 364 | ||
365 | |||
366 | #define __wait_event_interruptible_locked(wq, condition, exclusive, irq) \ | ||
367 | ({ \ | ||
368 | int __ret = 0; \ | ||
369 | DEFINE_WAIT(__wait); \ | ||
370 | if (exclusive) \ | ||
371 | __wait.flags |= WQ_FLAG_EXCLUSIVE; \ | ||
372 | do { \ | ||
373 | if (likely(list_empty(&__wait.task_list))) \ | ||
374 | __add_wait_queue_tail(&(wq), &__wait); \ | ||
375 | set_current_state(TASK_INTERRUPTIBLE); \ | ||
376 | if (signal_pending(current)) { \ | ||
377 | __ret = -ERESTARTSYS; \ | ||
378 | break; \ | ||
379 | } \ | ||
380 | if (irq) \ | ||
381 | spin_unlock_irq(&(wq).lock); \ | ||
382 | else \ | ||
383 | spin_unlock(&(wq).lock); \ | ||
384 | schedule(); \ | ||
385 | if (irq) \ | ||
386 | spin_lock_irq(&(wq).lock); \ | ||
387 | else \ | ||
388 | spin_lock(&(wq).lock); \ | ||
389 | } while (!(condition)); \ | ||
390 | __remove_wait_queue(&(wq), &__wait); \ | ||
391 | __set_current_state(TASK_RUNNING); \ | ||
392 | __ret; \ | ||
393 | }) | ||
394 | |||
395 | |||
396 | /** | ||
397 | * wait_event_interruptible_locked - sleep until a condition gets true | ||
398 | * @wq: the waitqueue to wait on | ||
399 | * @condition: a C expression for the event to wait for | ||
400 | * | ||
401 | * The process is put to sleep (TASK_INTERRUPTIBLE) until the | ||
402 | * @condition evaluates to true or a signal is received. | ||
403 | * The @condition is checked each time the waitqueue @wq is woken up. | ||
404 | * | ||
405 | * It must be called with wq.lock being held. This spinlock is | ||
406 | * unlocked while sleeping but @condition testing is done while lock | ||
407 | * is held and when this macro exits the lock is held. | ||
408 | * | ||
409 | * The lock is locked/unlocked using spin_lock()/spin_unlock() | ||
410 | * functions which must match the way they are locked/unlocked outside | ||
411 | * of this macro. | ||
412 | * | ||
413 | * wake_up_locked() has to be called after changing any variable that could | ||
414 | * change the result of the wait condition. | ||
415 | * | ||
416 | * The function will return -ERESTARTSYS if it was interrupted by a | ||
417 | * signal and 0 if @condition evaluated to true. | ||
418 | */ | ||
419 | #define wait_event_interruptible_locked(wq, condition) \ | ||
420 | ((condition) \ | ||
421 | ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 0)) | ||
422 | |||
423 | /** | ||
424 | * wait_event_interruptible_locked_irq - sleep until a condition gets true | ||
425 | * @wq: the waitqueue to wait on | ||
426 | * @condition: a C expression for the event to wait for | ||
427 | * | ||
428 | * The process is put to sleep (TASK_INTERRUPTIBLE) until the | ||
429 | * @condition evaluates to true or a signal is received. | ||
430 | * The @condition is checked each time the waitqueue @wq is woken up. | ||
431 | * | ||
432 | * It must be called with wq.lock being held. This spinlock is | ||
433 | * unlocked while sleeping but @condition testing is done while lock | ||
434 | * is held and when this macro exits the lock is held. | ||
435 | * | ||
436 | * The lock is locked/unlocked using spin_lock_irq()/spin_unlock_irq() | ||
437 | * functions which must match the way they are locked/unlocked outside | ||
438 | * of this macro. | ||
439 | * | ||
440 | * wake_up_locked() has to be called after changing any variable that could | ||
441 | * change the result of the wait condition. | ||
442 | * | ||
443 | * The function will return -ERESTARTSYS if it was interrupted by a | ||
444 | * signal and 0 if @condition evaluated to true. | ||
445 | */ | ||
446 | #define wait_event_interruptible_locked_irq(wq, condition) \ | ||
447 | ((condition) \ | ||
448 | ? 0 : __wait_event_interruptible_locked(wq, condition, 0, 1)) | ||
449 | |||
450 | /** | ||
451 | * wait_event_interruptible_exclusive_locked - sleep exclusively until a condition gets true | ||
452 | * @wq: the waitqueue to wait on | ||
453 | * @condition: a C expression for the event to wait for | ||
454 | * | ||
455 | * The process is put to sleep (TASK_INTERRUPTIBLE) until the | ||
456 | * @condition evaluates to true or a signal is received. | ||
457 | * The @condition is checked each time the waitqueue @wq is woken up. | ||
458 | * | ||
459 | * It must be called with wq.lock being held. This spinlock is | ||
460 | * unlocked while sleeping but @condition testing is done while lock | ||
461 | * is held and when this macro exits the lock is held. | ||
462 | * | ||
463 | * The lock is locked/unlocked using spin_lock()/spin_unlock() | ||
464 | * functions which must match the way they are locked/unlocked outside | ||
465 | * of this macro. | ||
466 | * | ||
467 | * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag | ||
468 | * set thus when other process waits process on the list if this | ||
469 | * process is awaken further processes are not considered. | ||
470 | * | ||
471 | * wake_up_locked() has to be called after changing any variable that could | ||
472 | * change the result of the wait condition. | ||
473 | * | ||
474 | * The function will return -ERESTARTSYS if it was interrupted by a | ||
475 | * signal and 0 if @condition evaluated to true. | ||
476 | */ | ||
477 | #define wait_event_interruptible_exclusive_locked(wq, condition) \ | ||
478 | ((condition) \ | ||
479 | ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 0)) | ||
480 | |||
481 | /** | ||
482 | * wait_event_interruptible_exclusive_locked_irq - sleep until a condition gets true | ||
483 | * @wq: the waitqueue to wait on | ||
484 | * @condition: a C expression for the event to wait for | ||
485 | * | ||
486 | * The process is put to sleep (TASK_INTERRUPTIBLE) until the | ||
487 | * @condition evaluates to true or a signal is received. | ||
488 | * The @condition is checked each time the waitqueue @wq is woken up. | ||
489 | * | ||
490 | * It must be called with wq.lock being held. This spinlock is | ||
491 | * unlocked while sleeping but @condition testing is done while lock | ||
492 | * is held and when this macro exits the lock is held. | ||
493 | * | ||
494 | * The lock is locked/unlocked using spin_lock_irq()/spin_unlock_irq() | ||
495 | * functions which must match the way they are locked/unlocked outside | ||
496 | * of this macro. | ||
497 | * | ||
498 | * The process is put on the wait queue with an WQ_FLAG_EXCLUSIVE flag | ||
499 | * set thus when other process waits process on the list if this | ||
500 | * process is awaken further processes are not considered. | ||
501 | * | ||
502 | * wake_up_locked() has to be called after changing any variable that could | ||
503 | * change the result of the wait condition. | ||
504 | * | ||
505 | * The function will return -ERESTARTSYS if it was interrupted by a | ||
506 | * signal and 0 if @condition evaluated to true. | ||
507 | */ | ||
508 | #define wait_event_interruptible_exclusive_locked_irq(wq, condition) \ | ||
509 | ((condition) \ | ||
510 | ? 0 : __wait_event_interruptible_locked(wq, condition, 1, 1)) | ||
511 | |||
512 | |||
513 | |||
365 | #define __wait_event_killable(wq, condition, ret) \ | 514 | #define __wait_event_killable(wq, condition, ret) \ |
366 | do { \ | 515 | do { \ |
367 | DEFINE_WAIT(__wait); \ | 516 | DEFINE_WAIT(__wait); \ |
diff --git a/kernel/sched.c b/kernel/sched.c index 3c2a54f70ffe..9584b66c249a 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3950,6 +3950,7 @@ void __wake_up_locked(wait_queue_head_t *q, unsigned int mode) | |||
3950 | { | 3950 | { |
3951 | __wake_up_common(q, mode, 1, 0, NULL); | 3951 | __wake_up_common(q, mode, 1, 0, NULL); |
3952 | } | 3952 | } |
3953 | EXPORT_SYMBOL_GPL(__wake_up_locked); | ||
3953 | 3954 | ||
3954 | void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key) | 3955 | void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key) |
3955 | { | 3956 | { |