Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 359520
b: refs/heads/master
c: 686855f
h: refs/heads/master
v: v3
  • Loading branch information
Vladimir Davydov authored and Jens Axboe committed Feb 15, 2013
1 parent eead25a commit fa6cb15
Show file tree
Hide file tree
Showing 3 changed files with 56 additions and 6 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9fb0a7da0c528d9bd49b597aa63b1fe2216c7203
refs/heads/master: 686855f5d833178e518d79e7912cdb3268a9fa69
3 changes: 3 additions & 0 deletions trunk/include/linux/completion.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,13 @@ static inline void init_completion(struct completion *x)
}

extern void wait_for_completion(struct completion *);
extern void wait_for_completion_io(struct completion *);
extern int wait_for_completion_interruptible(struct completion *x);
extern int wait_for_completion_killable(struct completion *x);
extern unsigned long wait_for_completion_timeout(struct completion *x,
unsigned long timeout);
extern unsigned long wait_for_completion_io_timeout(struct completion *x,
unsigned long timeout);
extern long wait_for_completion_interruptible_timeout(
struct completion *x, unsigned long timeout);
extern long wait_for_completion_killable_timeout(
Expand Down
57 changes: 52 additions & 5 deletions trunk/kernel/sched/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -3267,7 +3267,8 @@ void complete_all(struct completion *x)
EXPORT_SYMBOL(complete_all);

static inline long __sched
do_wait_for_common(struct completion *x, long timeout, int state)
do_wait_for_common(struct completion *x,
long (*action)(long), long timeout, int state)
{
if (!x->done) {
DECLARE_WAITQUEUE(wait, current);
Expand All @@ -3280,7 +3281,7 @@ do_wait_for_common(struct completion *x, long timeout, int state)
}
__set_current_state(state);
spin_unlock_irq(&x->wait.lock);
timeout = schedule_timeout(timeout);
timeout = action(timeout);
spin_lock_irq(&x->wait.lock);
} while (!x->done && timeout);
__remove_wait_queue(&x->wait, &wait);
Expand All @@ -3291,17 +3292,30 @@ do_wait_for_common(struct completion *x, long timeout, int state)
return timeout ?: 1;
}

static long __sched
wait_for_common(struct completion *x, long timeout, int state)
static inline long __sched
__wait_for_common(struct completion *x,
long (*action)(long), long timeout, int state)
{
might_sleep();

spin_lock_irq(&x->wait.lock);
timeout = do_wait_for_common(x, timeout, state);
timeout = do_wait_for_common(x, action, timeout, state);
spin_unlock_irq(&x->wait.lock);
return timeout;
}

static long __sched
wait_for_common(struct completion *x, long timeout, int state)
{
return __wait_for_common(x, schedule_timeout, timeout, state);
}

static long __sched
wait_for_common_io(struct completion *x, long timeout, int state)
{
return __wait_for_common(x, io_schedule_timeout, timeout, state);
}

/**
* wait_for_completion: - waits for completion of a task
* @x: holds the state of this particular completion
Expand Down Expand Up @@ -3337,6 +3351,39 @@ wait_for_completion_timeout(struct completion *x, unsigned long timeout)
}
EXPORT_SYMBOL(wait_for_completion_timeout);

/**
* wait_for_completion_io: - waits for completion of a task
* @x: holds the state of this particular completion
*
* This waits to be signaled for completion of a specific task. It is NOT
* interruptible and there is no timeout. The caller is accounted as waiting
* for IO.
*/
void __sched wait_for_completion_io(struct completion *x)
{
wait_for_common_io(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
}
EXPORT_SYMBOL(wait_for_completion_io);

/**
* wait_for_completion_io_timeout: - waits for completion of a task (w/timeout)
* @x: holds the state of this particular completion
* @timeout: timeout value in jiffies
*
* This waits for either a completion of a specific task to be signaled or for a
* specified timeout to expire. The timeout is in jiffies. It is not
* interruptible. The caller is accounted as waiting for IO.
*
* The return value is 0 if timed out, and positive (at least 1, or number of
* jiffies left till timeout) if completed.
*/
unsigned long __sched
wait_for_completion_io_timeout(struct completion *x, unsigned long timeout)
{
return wait_for_common_io(x, timeout, TASK_UNINTERRUPTIBLE);
}
EXPORT_SYMBOL(wait_for_completion_io_timeout);

/**
* wait_for_completion_interruptible: - waits for completion of a task (w/intr)
* @x: holds the state of this particular completion
Expand Down

0 comments on commit fa6cb15

Please sign in to comment.