aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/wait.h149
-rw-r--r--kernel/sched.c1
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) \
366do { \ 515do { \
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}
3953EXPORT_SYMBOL_GPL(__wake_up_locked);
3953 3954
3954void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key) 3955void __wake_up_locked_key(wait_queue_head_t *q, unsigned int mode, void *key)
3955{ 3956{