summaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorOleg Nesterov <oleg@tv-sign.ru>2008-06-20 16:32:20 +0200
committerIngo Molnar <mingo@elte.hu>2008-06-20 17:15:49 +0200
commitea71a546706dfdad72462624394e1e472c6bf34f (patch)
treeeb6f257c73510deee995f330947de4624e9b404b /kernel
parentsched: fix wait_for_completion_timeout() spurious failure under heavy load (diff)
downloadlinux-ea71a546706dfdad72462624394e1e472c6bf34f.tar.xz
linux-ea71a546706dfdad72462624394e1e472c6bf34f.zip
sched: refactor wait_for_completion_timeout()
Simplify the code and fix the boundary condition of wait_for_completion_timeout(,0). We can kill the first __remove_wait_queue() as well. Signed-off-by: Ingo Molnar <mingo@elte.hu> Acked-by: Peter Zijlstra <a.p.zijlstra@chello.nl>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/sched.c24
1 files changed, 6 insertions, 18 deletions
diff --git a/kernel/sched.c b/kernel/sched.c
index 577f160131bd..bebf9788f45e 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -4398,32 +4398,20 @@ do_wait_for_common(struct completion *x, long timeout, int state)
signal_pending(current)) ||
(state == TASK_KILLABLE &&
fatal_signal_pending(current))) {
- __remove_wait_queue(&x->wait, &wait);
- return -ERESTARTSYS;
+ timeout = -ERESTARTSYS;
+ break;
}
__set_current_state(state);
spin_unlock_irq(&x->wait.lock);
timeout = schedule_timeout(timeout);
spin_lock_irq(&x->wait.lock);
-
- /*
- * If the completion has arrived meanwhile
- * then return 1 jiffy time left:
- */
- if (x->done && !timeout) {
- timeout = 1;
- break;
- }
-
- if (!timeout) {
- __remove_wait_queue(&x->wait, &wait);
- return timeout;
- }
- } while (!x->done);
+ } while (!x->done && timeout);
__remove_wait_queue(&x->wait, &wait);
+ if (!x->done)
+ return timeout;
}
x->done--;
- return timeout;
+ return timeout ?: 1;
}
static long __sched