basic and stupid question on wait_event and wake_up

Domen Puncer domen.puncer at telargo.com
Mon Aug 13 18:47:36 EST 2007


On 13/08/07 08:33 +0000, Ming Liu wrote:
> Dear Domen,
> Thanks for your reply first. 
> 
> >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)
> 
> >From the source code, it seems like that this mechanism doesn't use 
> msleep(), 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.

> 
> 
> >- 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


More information about the Linuxppc-embedded mailing list