Re: basic and stupid question on wait_event and wake_up
From: Domen Puncer <hidden>
Date: 2007-08-13 08:47:36
On 13/08/07 08:33 +0000, Ming Liu wrote:
Dear Domen, Thanks for your reply first.quoted
I understand it this way: - condition Just checking the condition is one way (if you don't have a wake_up source, like an interrupt), but that's not really what wait_event does. It would be something like while (condition) { msleep(10); } There was some talk on poll_wait(), but I don't know what happened to it.So you mean in my senario (wake the process up in the interrupt handler), I needn't to use wake_up at all? A "condition == true" in the interrupt handler is enough to wake the sleeping process up? Am I right?
No.
Without the wake_up(), wait_event() would (normally) just wait
... and wait... and wait...
When you set your task_state to TASK_{UN,}INTERRUPTIBLE you need to have
a way to wake it up again.
That's why I used msleep(10) in my example. It would check condition every
10 ms.
I checked the source code in linux/wait.h and here is the defination of wait_event: #define __wait_event(wq, condition) do { DEFINE_WAIT(__wait); for (;;) { \ prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE); if (condition) break; schedule(); } finish_wait(&wq, &__wait); } while (0) #define wait_event(wq, condition) do { if (condition) break; __wait_event(wq, condition); } while (0)quoted
From the source code, it seems like that this mechanism doesn't usemsleep(), like what you mentioned, to release its executing. Instead, it uses schedule() to do that.
msleep() was just an example of how to do polling wait. Didn't mean to confuze you there, sorry.
quoted
- wake_up Just wake_up isn't enough, you get a race: | interrupt handler | process | ------------------------------------------ | do_something() | | | wake_up() | | | ... | wait on wq | And so you have a process waiting on waitqueue, that just missed the wakeup. Obviously should not be used. - wake_up & condition | interrupt handler | process | ------------------------------------------ | flag = 1 | | | wake_up() | | | ... | wait_event | | ... | flag = 0 | This will work properly and if wait_event misses a wake_up, the condition check (flag) will kick in before putting it to sleep.Thanks for your explaining on the race problem. I can understand this now. However I still cannot understand, is such a problem: In the above figures for my case, if flag=1 could wake the process up, then what's the use of wake_up()? From my understanding if the condition turns true, then the process which depends on this condition will be waken up. Thus what's the exact use of wake_up()? Also in my program, I tried to remove wake_up() sentence and it seems that there is no difference on the result.
As explained above, flag = 1 does not wake up the process, it just makes sure you don't have miss-the-wakeup race. Domen
Thanks for the explanation. BR Ming