basic and stupid question on wait_event and wake_up

8 messages, 3 authors, 2007-08-13 · open the first message on its own page

basic and stupid question on wait_event and wake_up

From: Ming Liu <hidden>
Date: 2007-08-12 13:57:01

Dear all,
I am reading LDD(V3) chapter 6 on the topic of wait_event(queue, condition) 
and wake_up(queue) functions. I am quite confused on the sayings. One is 
"Until condition evaluates to a true value, the process continues to 
sleep", which looks like that 'condition' is the one who wake up the 
process from its sleeping. However the other saying is "The basic function 
that wakes up sleeping processes is called wake_up, and wake_up wakes up 
all processes waiting on the given queue" So who is the exact one to wake 
the sleeping process up at all, condition or wake_up? From my 
understanding, if the condition becomes true, then the sleeping process 
will leave its sleeping status and wake up. Then what's the use of wake_up 
function? 

My senario could be described as: in my char device driver, I use one ioctl 
command to initiate a DMA transfer. After all related registers are 
initiated, this process will be put to sleep for saving CPU cycles. In the 
interrupt handler which is for a DMA_done, I wake that process up and 
resume its following executing. With this method, in my application program 
if I release a DMA initiation command, it is a Blocking operation and it 
will wait until the DMA transfer is done. 

Perhaps my question is quite simple or basic. Thanks for any explanation 
and comment on this topic in my senario from you experts. Thanks a lot.

Br
Ming

_________________________________________________________________
与联机的朋友进行交流,请使用 MSN Messenger:  http://messenger.msn.com/cn  

Re: basic and stupid question on wait_event and wake_up

From: Domen Puncer <hidden>
Date: 2007-08-13 07:54:23

On 12/08/07 13:57 +0000, Ming Liu wrote:
Dear all,
I am reading LDD(V3) chapter 6 on the topic of wait_event(queue, conditio=
n)=20
and wake_up(queue) functions. I am quite confused on the sayings. One is=
=20
"Until condition evaluates to a true value, the process continues to=20
sleep", which looks like that 'condition' is the one who wake up the=20
process from its sleeping. However the other saying is "The basic functio=
n=20
that wakes up sleeping processes is called wake_up, and wake_up wakes up=
=20
all processes waiting on the given queue" So who is the exact one to wake=
=20
the sleeping process up at all, condition or wake_up? From my=20
understanding, if the condition becomes true, then the sleeping process=
=20
will leave its sleeping status and wake up. Then what's the use of wake_u=
p=20
function?=20
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.

- 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 =3D 1            |                |
  |   wake_up()           |                |
  |   ...                 |   wait_event   |
  |   ...                 |   flag =3D 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.

=20
My senario could be described as: in my char device driver, I use one ioc=
tl=20
command to initiate a DMA transfer. After all related registers are=20
initiated, this process will be put to sleep for saving CPU cycles. In th=
e=20
interrupt handler which is for a DMA_done, I wake that process up and=20
resume its following executing. With this method, in my application progr=
am=20
if I release a DMA initiation command, it is a Blocking operation and it=
=20
will wait until the DMA transfer is done.=20
Looks like you should use the "wake_up and condition" option.


	Domen
=20
Perhaps my question is quite simple or basic. Thanks for any explanation=
=20
and comment on this topic in my senario from you experts. Thanks a lot.
=20
Br
Ming
=20
_________________________________________________________________
=E4=B8=8E=E8=81=94=E6=9C=BA=E7=9A=84=E6=9C=8B=E5=8F=8B=E8=BF=9B=E8=A1=8C=
=E4=BA=A4=E6=B5=81=EF=BC=8C=E8=AF=B7=E4=BD=BF=E7=94=A8 MSN Messenger:  http=
://messenger.msn.com/cn =20
=20
_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

Re: basic and stupid question on wait_event and wake_up

From: Ming Liu <hidden>
Date: 2007-08-13 08:33:39

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?

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. 

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

Thanks for the explanation.

BR
Ming

_________________________________________________________________
与联机的朋友进行交流,请使用 MSN Messenger:  http://messenger.msn.com/cn  

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

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  

Re: basic and stupid question on wait_event and wake_up

From: Laurent Pinchart <hidden>
Date: 2007-08-13 09:30:15

On Monday 13 August 2007 11:22, Ming Liu wrote:
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?
Actually, the process will wake up every time you call wake_up(). It will then 
evaluate the condition. If the condition is true, the process will return 
from wait_event. If the condition is false, it will go back to sleep.

Best regards,

Laurent Pinchart

Re: basic and stupid question on wait_event and wake_up

From: Domen Puncer <hidden>
Date: 2007-08-13 09:31:07

On 13/08/07 09:22 +0000, Ming Liu wrote:
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?
Right.


	Domen

Re: basic and stupid question on wait_event and wake_up

From: Ming Liu <hidden>
Date: 2007-08-13 09:46:17

Thank you so much for your explanation. Now I am quite clear on this topic. 


Domen, Sorry for my misspelling of your name. That should be "Domen" not 
"Momen". Sorry for that. :)

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 11:31:07 +0200

On 13/08/07 09:22 +0000, Ming Liu wrote:
quoted
Dear Momen,
OK. I see now. So you mean condition is only to judge whether a 
sleeping
quoted
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
quoted
the function of wake_up, right? We just execute wake_up() and then 
check if
quoted
condition is true. If yes, the process will leave its sleeping and wake 
up;
quoted
if not, it keep sleeping. Am I right?
Right.


Domen
_________________________________________________________________
免费下载 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