Thread (8 messages) flat view 8 messages, 3 authors, 2007-08-13

Re: basic and stupid question on wait_event and wake_up

From: Ming Liu <hidden>
Date: 2007-08-13 09:22:14

Dear Momen,
OK. I see now. So you mean condition is only to judge whether a sleeping 
process could be waken up or not when wake_up() is executed in other 
processes or interrupt handlers. What really wakes the process up is still 
the function of wake_up, right? We just execute wake_up() and then check if 
condition is true. If yes, the process will leave its sleeping and wake up; 
if not, it keep sleeping. Am I right?

BR
Ming

From: Domen Puncer <redacted>
To: Ming Liu <redacted>
CC: Linuxppc-embedded@ozlabs.org
Subject: Re: basic and stupid question on wait_event and wake_up
Date: Mon, 13 Aug 2007 10:47:36 +0200

On 13/08/07 08:33 +0000, Ming Liu wrote:
quoted
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.
quoted
quoted
 It would be something like
while (condition) {
	msleep(10);
}
 There was some talk on poll_wait(), but I don't know what happened 
to
quoted
quoted
 it.
So you mean in my senario (wake the process up in the interrupt 
handler), I
quoted
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.
quoted
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 use
msleep(), like what you mentioned, to release its executing. Instead, 
it
quoted
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
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.
quoted
However I still cannot understand, is such a problem: In the above 
figures
quoted
for my case, if flag=1 could wake the process up, then what's the use 
of
quoted
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
quoted
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
quoted
Thanks for the explanation.

BR
Ming
_________________________________________________________________
免费下载 MSN Explorer:   http://explorer.msn.com/lccn  
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help