diff options
Diffstat (limited to 'kernel/sched.c')
-rw-r--r-- | kernel/sched.c | 71 |
1 files changed, 41 insertions, 30 deletions
diff --git a/kernel/sched.c b/kernel/sched.c index ef6b6bb3e0b2..0e3caf742ae3 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -3699,74 +3699,85 @@ out: | |||
3699 | } | 3699 | } |
3700 | EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); | 3700 | EXPORT_SYMBOL(wait_for_completion_interruptible_timeout); |
3701 | 3701 | ||
3702 | 3702 | static inline void | |
3703 | #define SLEEP_ON_VAR \ | 3703 | sleep_on_head(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags) |
3704 | unsigned long flags; \ | 3704 | { |
3705 | wait_queue_t wait; \ | 3705 | spin_lock_irqsave(&q->lock, *flags); |
3706 | init_waitqueue_entry(&wait, current); | 3706 | __add_wait_queue(q, wait); |
3707 | |||
3708 | #define SLEEP_ON_HEAD \ | ||
3709 | spin_lock_irqsave(&q->lock,flags); \ | ||
3710 | __add_wait_queue(q, &wait); \ | ||
3711 | spin_unlock(&q->lock); | 3707 | spin_unlock(&q->lock); |
3708 | } | ||
3712 | 3709 | ||
3713 | #define SLEEP_ON_TAIL \ | 3710 | static inline void |
3714 | spin_lock_irq(&q->lock); \ | 3711 | sleep_on_tail(wait_queue_head_t *q, wait_queue_t *wait, unsigned long *flags) |
3715 | __remove_wait_queue(q, &wait); \ | 3712 | { |
3716 | spin_unlock_irqrestore(&q->lock, flags); | 3713 | spin_lock_irq(&q->lock); |
3714 | __remove_wait_queue(q, wait); | ||
3715 | spin_unlock_irqrestore(&q->lock, *flags); | ||
3716 | } | ||
3717 | 3717 | ||
3718 | void fastcall __sched interruptible_sleep_on(wait_queue_head_t *q) | 3718 | void __sched interruptible_sleep_on(wait_queue_head_t *q) |
3719 | { | 3719 | { |
3720 | SLEEP_ON_VAR | 3720 | unsigned long flags; |
3721 | wait_queue_t wait; | ||
3722 | |||
3723 | init_waitqueue_entry(&wait, current); | ||
3721 | 3724 | ||
3722 | current->state = TASK_INTERRUPTIBLE; | 3725 | current->state = TASK_INTERRUPTIBLE; |
3723 | 3726 | ||
3724 | SLEEP_ON_HEAD | 3727 | sleep_on_head(q, &wait, &flags); |
3725 | schedule(); | 3728 | schedule(); |
3726 | SLEEP_ON_TAIL | 3729 | sleep_on_tail(q, &wait, &flags); |
3727 | } | 3730 | } |
3728 | EXPORT_SYMBOL(interruptible_sleep_on); | 3731 | EXPORT_SYMBOL(interruptible_sleep_on); |
3729 | 3732 | ||
3730 | long fastcall __sched | 3733 | long __sched |
3731 | interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) | 3734 | interruptible_sleep_on_timeout(wait_queue_head_t *q, long timeout) |
3732 | { | 3735 | { |
3733 | SLEEP_ON_VAR | 3736 | unsigned long flags; |
3737 | wait_queue_t wait; | ||
3738 | |||
3739 | init_waitqueue_entry(&wait, current); | ||
3734 | 3740 | ||
3735 | current->state = TASK_INTERRUPTIBLE; | 3741 | current->state = TASK_INTERRUPTIBLE; |
3736 | 3742 | ||
3737 | SLEEP_ON_HEAD | 3743 | sleep_on_head(q, &wait, &flags); |
3738 | timeout = schedule_timeout(timeout); | 3744 | timeout = schedule_timeout(timeout); |
3739 | SLEEP_ON_TAIL | 3745 | sleep_on_tail(q, &wait, &flags); |
3740 | 3746 | ||
3741 | return timeout; | 3747 | return timeout; |
3742 | } | 3748 | } |
3743 | EXPORT_SYMBOL(interruptible_sleep_on_timeout); | 3749 | EXPORT_SYMBOL(interruptible_sleep_on_timeout); |
3744 | 3750 | ||
3745 | void fastcall __sched sleep_on(wait_queue_head_t *q) | 3751 | void __sched sleep_on(wait_queue_head_t *q) |
3746 | { | 3752 | { |
3747 | SLEEP_ON_VAR | 3753 | unsigned long flags; |
3754 | wait_queue_t wait; | ||
3755 | |||
3756 | init_waitqueue_entry(&wait, current); | ||
3748 | 3757 | ||
3749 | current->state = TASK_UNINTERRUPTIBLE; | 3758 | current->state = TASK_UNINTERRUPTIBLE; |
3750 | 3759 | ||
3751 | SLEEP_ON_HEAD | 3760 | sleep_on_head(q, &wait, &flags); |
3752 | schedule(); | 3761 | schedule(); |
3753 | SLEEP_ON_TAIL | 3762 | sleep_on_tail(q, &wait, &flags); |
3754 | } | 3763 | } |
3755 | EXPORT_SYMBOL(sleep_on); | 3764 | EXPORT_SYMBOL(sleep_on); |
3756 | 3765 | ||
3757 | long fastcall __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) | 3766 | long __sched sleep_on_timeout(wait_queue_head_t *q, long timeout) |
3758 | { | 3767 | { |
3759 | SLEEP_ON_VAR | 3768 | unsigned long flags; |
3769 | wait_queue_t wait; | ||
3770 | |||
3771 | init_waitqueue_entry(&wait, current); | ||
3760 | 3772 | ||
3761 | current->state = TASK_UNINTERRUPTIBLE; | 3773 | current->state = TASK_UNINTERRUPTIBLE; |
3762 | 3774 | ||
3763 | SLEEP_ON_HEAD | 3775 | sleep_on_head(q, &wait, &flags); |
3764 | timeout = schedule_timeout(timeout); | 3776 | timeout = schedule_timeout(timeout); |
3765 | SLEEP_ON_TAIL | 3777 | sleep_on_tail(q, &wait, &flags); |
3766 | 3778 | ||
3767 | return timeout; | 3779 | return timeout; |
3768 | } | 3780 | } |
3769 | |||
3770 | EXPORT_SYMBOL(sleep_on_timeout); | 3781 | EXPORT_SYMBOL(sleep_on_timeout); |
3771 | 3782 | ||
3772 | #ifdef CONFIG_RT_MUTEXES | 3783 | #ifdef CONFIG_RT_MUTEXES |