123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343 |
- void complete(struct completion *x)
- {
- unsigned long flags;
- raw_spin_lock_irqsave(&x->wait.lock, flags);
- if (x->done != UINT_MAX)
- x->done++;
- swake_up_locked(&x->wait);
- raw_spin_unlock_irqrestore(&x->wait.lock, flags);
- }
- EXPORT_SYMBOL(complete);
- void complete_all(struct completion *x)
- {
- unsigned long flags;
- lockdep_assert_RT_in_threaded_ctx();
- raw_spin_lock_irqsave(&x->wait.lock, flags);
- x->done = UINT_MAX;
- swake_up_all_locked(&x->wait);
- raw_spin_unlock_irqrestore(&x->wait.lock, flags);
- }
- EXPORT_SYMBOL(complete_all);
- static inline long __sched
- do_wait_for_common(struct completion *x,
- long (*action)(long), long timeout, int state)
- {
- if (!x->done) {
- DECLARE_SWAITQUEUE(wait);
- do {
- if (signal_pending_state(state, current)) {
- timeout = -ERESTARTSYS;
- break;
- }
- __prepare_to_swait(&x->wait, &wait);
- __set_current_state(state);
- raw_spin_unlock_irq(&x->wait.lock);
- timeout = action(timeout);
- raw_spin_lock_irq(&x->wait.lock);
- } while (!x->done && timeout);
- __finish_swait(&x->wait, &wait);
- if (!x->done)
- return timeout;
- }
- if (x->done != UINT_MAX)
- x->done--;
- return timeout ?: 1;
- }
- static inline long __sched
- __wait_for_common(struct completion *x,
- long (*action)(long), long timeout, int state)
- {
- might_sleep();
- complete_acquire(x);
- raw_spin_lock_irq(&x->wait.lock);
- timeout = do_wait_for_common(x, action, timeout, state);
- raw_spin_unlock_irq(&x->wait.lock);
- complete_release(x);
- 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);
- }
- void __sched wait_for_completion(struct completion *x)
- {
- wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_UNINTERRUPTIBLE);
- }
- EXPORT_SYMBOL(wait_for_completion);
- unsigned long __sched
- wait_for_completion_timeout(struct completion *x, unsigned long timeout)
- {
- return wait_for_common(x, timeout, TASK_UNINTERRUPTIBLE);
- }
- EXPORT_SYMBOL(wait_for_completion_timeout);
- 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);
- 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);
- int __sched wait_for_completion_interruptible(struct completion *x)
- {
- long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_INTERRUPTIBLE);
- if (t == -ERESTARTSYS)
- return t;
- return 0;
- }
- EXPORT_SYMBOL(wait_for_completion_interruptible);
- long __sched
- wait_for_completion_interruptible_timeout(struct completion *x,
- unsigned long timeout)
- {
- return wait_for_common(x, timeout, TASK_INTERRUPTIBLE);
- }
- EXPORT_SYMBOL(wait_for_completion_interruptible_timeout);
- int __sched wait_for_completion_killable(struct completion *x)
- {
- long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, TASK_KILLABLE);
- if (t == -ERESTARTSYS)
- return t;
- return 0;
- }
- EXPORT_SYMBOL(wait_for_completion_killable);
- int __sched wait_for_completion_state(struct completion *x, unsigned int state)
- {
- long t = wait_for_common(x, MAX_SCHEDULE_TIMEOUT, state);
- if (t == -ERESTARTSYS)
- return t;
- return 0;
- }
- EXPORT_SYMBOL(wait_for_completion_state);
- long __sched
- wait_for_completion_killable_timeout(struct completion *x,
- unsigned long timeout)
- {
- return wait_for_common(x, timeout, TASK_KILLABLE);
- }
- EXPORT_SYMBOL(wait_for_completion_killable_timeout);
- bool try_wait_for_completion(struct completion *x)
- {
- unsigned long flags;
- bool ret = true;
-
- if (!READ_ONCE(x->done))
- return false;
- raw_spin_lock_irqsave(&x->wait.lock, flags);
- if (!x->done)
- ret = false;
- else if (x->done != UINT_MAX)
- x->done--;
- raw_spin_unlock_irqrestore(&x->wait.lock, flags);
- return ret;
- }
- EXPORT_SYMBOL(try_wait_for_completion);
- bool completion_done(struct completion *x)
- {
- unsigned long flags;
- if (!READ_ONCE(x->done))
- return false;
-
- raw_spin_lock_irqsave(&x->wait.lock, flags);
- raw_spin_unlock_irqrestore(&x->wait.lock, flags);
- return true;
- }
- EXPORT_SYMBOL(completion_done);
|