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