code for wait_event_interruptible
It's in include/linux/wait.h
:
#define wait_event_interruptible(wq, condition) \
({ \
int __ret = 0; \
if (!(condition)) \
__wait_event_interruptible(wq, condition, __ret); \
__ret; \
})
...
#define __wait_event_interruptible(wq, condition, ret) \
do { \
DEFINE_WAIT(__wait); \
\
for (;;) { \
prepare_to_wait(&wq, &__wait, TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if (!signal_pending(current)) { \
schedule(); \
continue; \
} \
ret = -ERESTARTSYS; \
break; \
} \
finish_wait(&wq, &__wait); \
} while (0)
Wait_event_interruptible Vs wake_up_interruptible
- When the condition is already true, there is no need to wait.
(Thewait_event
* functions check the condition also before they begin the actual wait.) - When the condition is still false, it will go back to sleep.
race condition between wait_event and wake_up
Since the interrupt can occur between the call to wait_event_interruptible
and flag = 0
, it would affect the flag
variable in an unwanted way.
Note that even on a UP machine, the kernel could be preemptive depending on the configuration, and that code would be affected as a result.
Also, I advice to not use a simple 'int' flag. Instead, you should use atomic_t
and atomic_dec/inc_*
operations. See the implementation of completions inside the kernel, it does something similar to what you are doing here.
About the question itself:
If you'll look in the code of wait_event_interruptible
you'll see that the sleep doesn't take place if the condition is true - so your problem is a non-problem.
From sleep_on() to wait_event()?
You may define sleep_on
function as it has been defined in pre-3.15 kernels. Like this:
void
sleep_on(wait_queue_head_t *q)
{
unsigned long flags;
wait_queue_t wait;
init_waitqueue_entry(&wait, current);
__set_current_state(TASK_UNINTERRUPTIBLE);
spin_lock_irqsave(&q->lock, flags);
__add_wait_queue(q, &wait);
spin_unlock(&q->lock);
schedule();
spin_lock_irq(&q->lock);
__remove_wait_queue(q, &wait);
spin_unlock_irqrestore(&q->lock, flags);
}
(originated from the code of sleep_on_common
but with timeout things removed.)
For those who want to see the original code on kernel.org, see sleep_on_common()
with commit 32d01dc7be4e725ab85ce1d74e8f4adc02ad68dd
in April 2014 (a few days before the function was removed).
As for wait_event()
and friends, using constant condition is wrong:
- 'true' will never sleep
- 'false' will never woken up
Related Topics
Sublime Text 2 Build (Ctrl +B) Intel Fortran Compiler
Tcp Keepalive - Protocol Not Available
Mongodb Service Fails After Reboot
Shell: What Is The Purpose of ${Var:-} When Var Is Unset or Null
What Happens When I Sudo Bash -C
Set Preferred Listen Address in Weblogic 11G
A Wrong Size of "Len" Calculated by $ - Symbol with Fasm Equ
How to Export Daily Disk Usage to CSV Format in Shell Scripting
Succinct Way to Print All Lines Up Until The Last Line That Matches a Given Pattern
Posix: Pipe Syscall in Freebsd Vs Linux
Why a Static Library Can Depend on a Shared a Library
How to Get Argv from "Struct Linux_Binprm"
Container Running in Privileged Mode
Grep If The Next X Lines Doesn't Contain a Specific String
How to Use Multiple Threads for Zlib Compression (Same Input Source)
How to Populate /Dev with a Custom Directory with Udev
How to Remove Space/Tab from Command Output
Is There Some Ansible Equivalent to "Failed_When" for Success