diff options
-rw-r--r-- | include/linux/completion.h | 46 | ||||
-rw-r--r-- | kernel/sched.c | 46 |
2 files changed, 48 insertions, 44 deletions
diff --git a/include/linux/completion.h b/include/linux/completion.h index 57faa60de9bd..02ef8835999c 100644 --- a/include/linux/completion.h +++ b/include/linux/completion.h | |||
@@ -49,6 +49,8 @@ extern unsigned long wait_for_completion_timeout(struct completion *x, | |||
49 | unsigned long timeout); | 49 | unsigned long timeout); |
50 | extern unsigned long wait_for_completion_interruptible_timeout( | 50 | extern unsigned long wait_for_completion_interruptible_timeout( |
51 | struct completion *x, unsigned long timeout); | 51 | struct completion *x, unsigned long timeout); |
52 | extern bool try_wait_for_completion(struct completion *x); | ||
53 | extern bool completion_done(struct completion *x); | ||
52 | 54 | ||
53 | extern void complete(struct completion *); | 55 | extern void complete(struct completion *); |
54 | extern void complete_all(struct completion *); | 56 | extern void complete_all(struct completion *); |
@@ -56,48 +58,4 @@ extern void complete_all(struct completion *); | |||
56 | #define INIT_COMPLETION(x) ((x).done = 0) | 58 | #define INIT_COMPLETION(x) ((x).done = 0) |
57 | 59 | ||
58 | 60 | ||
59 | /** | ||
60 | * try_wait_for_completion - try to decrement a completion without blocking | ||
61 | * @x: completion structure | ||
62 | * | ||
63 | * Returns: 0 if a decrement cannot be done without blocking | ||
64 | * 1 if a decrement succeeded. | ||
65 | * | ||
66 | * If a completion is being used as a counting completion, | ||
67 | * attempt to decrement the counter without blocking. This | ||
68 | * enables us to avoid waiting if the resource the completion | ||
69 | * is protecting is not available. | ||
70 | */ | ||
71 | static inline bool try_wait_for_completion(struct completion *x) | ||
72 | { | ||
73 | int ret = 1; | ||
74 | |||
75 | spin_lock_irq(&x->wait.lock); | ||
76 | if (!x->done) | ||
77 | ret = 0; | ||
78 | else | ||
79 | x->done--; | ||
80 | spin_unlock_irq(&x->wait.lock); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | /** | ||
85 | * completion_done - Test to see if a completion has any waiters | ||
86 | * @x: completion structure | ||
87 | * | ||
88 | * Returns: 0 if there are waiters (wait_for_completion() in progress) | ||
89 | * 1 if there are no waiters. | ||
90 | * | ||
91 | */ | ||
92 | static inline bool completion_done(struct completion *x) | ||
93 | { | ||
94 | int ret = 1; | ||
95 | |||
96 | spin_lock_irq(&x->wait.lock); | ||
97 | if (!x->done) | ||
98 | ret = 0; | ||
99 | spin_unlock_irq(&x->wait.lock); | ||
100 | return ret; | ||
101 | } | ||
102 | |||
103 | #endif | 61 | #endif |
diff --git a/kernel/sched.c b/kernel/sched.c index d601fb0406ca..95e6ad3c231d 100644 --- a/kernel/sched.c +++ b/kernel/sched.c | |||
@@ -4669,6 +4669,52 @@ int __sched wait_for_completion_killable(struct completion *x) | |||
4669 | } | 4669 | } |
4670 | EXPORT_SYMBOL(wait_for_completion_killable); | 4670 | EXPORT_SYMBOL(wait_for_completion_killable); |
4671 | 4671 | ||
4672 | /** | ||
4673 | * try_wait_for_completion - try to decrement a completion without blocking | ||
4674 | * @x: completion structure | ||
4675 | * | ||
4676 | * Returns: 0 if a decrement cannot be done without blocking | ||
4677 | * 1 if a decrement succeeded. | ||
4678 | * | ||
4679 | * If a completion is being used as a counting completion, | ||
4680 | * attempt to decrement the counter without blocking. This | ||
4681 | * enables us to avoid waiting if the resource the completion | ||
4682 | * is protecting is not available. | ||
4683 | */ | ||
4684 | bool try_wait_for_completion(struct completion *x) | ||
4685 | { | ||
4686 | int ret = 1; | ||
4687 | |||
4688 | spin_lock_irq(&x->wait.lock); | ||
4689 | if (!x->done) | ||
4690 | ret = 0; | ||
4691 | else | ||
4692 | x->done--; | ||
4693 | spin_unlock_irq(&x->wait.lock); | ||
4694 | return ret; | ||
4695 | } | ||
4696 | EXPORT_SYMBOL(try_wait_for_completion); | ||
4697 | |||
4698 | /** | ||
4699 | * completion_done - Test to see if a completion has any waiters | ||
4700 | * @x: completion structure | ||
4701 | * | ||
4702 | * Returns: 0 if there are waiters (wait_for_completion() in progress) | ||
4703 | * 1 if there are no waiters. | ||
4704 | * | ||
4705 | */ | ||
4706 | bool completion_done(struct completion *x) | ||
4707 | { | ||
4708 | int ret = 1; | ||
4709 | |||
4710 | spin_lock_irq(&x->wait.lock); | ||
4711 | if (!x->done) | ||
4712 | ret = 0; | ||
4713 | spin_unlock_irq(&x->wait.lock); | ||
4714 | return ret; | ||
4715 | } | ||
4716 | EXPORT_SYMBOL(completion_done); | ||
4717 | |||
4672 | static long __sched | 4718 | static long __sched |
4673 | sleep_on_common(wait_queue_head_t *q, int state, long timeout) | 4719 | sleep_on_common(wait_queue_head_t *q, int state, long timeout) |
4674 | { | 4720 | { |