public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* questions on wait_event ...
@ 2005-12-23  0:04 Alexey Shinkin
  0 siblings, 0 replies; 6+ messages in thread
From: Alexey Shinkin @ 2005-12-23  0:04 UTC (permalink / raw)
  To: linux-kernel

Hi , all !
Could anyone please clarify one thing in that old well known
wait_event_... code (taken from 2.6.5 wait.h ):

#define __wait_event_interruptible(wq, condition, ret)          \
do {                                                                    \
        wait_queue_t __wait;                                     \
        init_waitqueue_entry(&__wait, current);           \
                                                                        \
        add_wait_queue(&wq, &__wait);                   \
        for (;;) {                                                      \
                set_current_state(TASK_INTERRUPTIBLE);    \
                if (condition)                                          \
                        break;
........................................

Is it possible that scheduling happen after set_current_state() but before
checking the condition ?
If yes - even if we will have condition==TRUE by this moment - the scheduler
will make the process to sleep anyway , right ?

Regards
Alex Shinkin

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! 
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: questions on wait_event ...
       [not found] <5mIFB-6PS-33@gated-at.bofh.it>
@ 2005-12-23  0:16 ` Robert Hancock
  2005-12-23  0:51   ` Alexey Shinkin
  0 siblings, 1 reply; 6+ messages in thread
From: Robert Hancock @ 2005-12-23  0:16 UTC (permalink / raw)
  To: linux-kernel

Alexey Shinkin wrote:
> Hi , all !
> Could anyone please clarify one thing in that old well known
> wait_event_... code (taken from 2.6.5 wait.h ):
> 
> #define __wait_event_interruptible(wq, condition, ret)          \
> do {                                                                    \
>        wait_queue_t __wait;                                     \
>        init_waitqueue_entry(&__wait, current);           \
>                                                                        \
>        add_wait_queue(&wq, &__wait);                   \
>        for (;;) {                                                      \
>                set_current_state(TASK_INTERRUPTIBLE);    \
>                if (condition)                                          \
>                        break;
> ........................................
> 
> Is it possible that scheduling happen after set_current_state() but before
> checking the condition ?
> If yes - even if we will have condition==TRUE by this moment - the 
> scheduler
> will make the process to sleep anyway , right ?

Yes, but since the condition would then have changed after we were put 
into the wait queue, they would have woken up the queue and we should be 
woken up again.

-- 
Robert Hancock      Saskatoon, SK, Canada
To email, remove "nospam" from hancockr@nospamshaw.ca
Home Page: http://www.roberthancock.com/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: questions on wait_event ...
  2005-12-23  0:16 ` questions on wait_event Robert Hancock
@ 2005-12-23  0:51   ` Alexey Shinkin
  2005-12-23  1:10     ` Steven Rostedt
  0 siblings, 1 reply; 6+ messages in thread
From: Alexey Shinkin @ 2005-12-23  0:51 UTC (permalink / raw)
  To: linux-kernel



>Alexey Shinkin wrote:
>>Hi , all !
>>Could anyone please clarify one thing in that old well known
>>wait_event_... code (taken from 2.6.5 wait.h ):
>>
>>#define __wait_event_interruptible(wq, condition, ret)          \
>>do {                                                                    \
>>        wait_queue_t __wait;                                     \
>>        init_waitqueue_entry(&__wait, current);           \
>>                                                                        \
>>        add_wait_queue(&wq, &__wait);                   \
>>        for (;;) {                                                      \
>>                set_current_state(TASK_INTERRUPTIBLE);    \
>>                if (condition)                                          \
>>                        break;
>>........................................
>>
>>Is it possible that scheduling happen after set_current_state() but before
>>checking the condition ?
>>If yes - even if we will have condition==TRUE by this moment - the 
>>scheduler
>>will make the process to sleep anyway , right ?
>
>Yes, but since the condition would then have changed after we were put into 
>the wait queue, they would have woken up the queue and we should be woken 
>up again.
>
>--
>Robert Hancock      Saskatoon, SK, Canada
>To email, remove "nospam" from hancockr@nospamshaw.ca
>Home Page: http://www.roberthancock.com/
>


And what if the condition have changed after we have checked it in 
wait_event() but
before calling __wait_event() and before putting the process into the wait 
queue ?
The process could not be woken up "in advance" , right ?


#define wait_event(wq, condition)        \
do {                                                   \
        if (condition)                                \
                break;                                 \
   /* and here we have condition changed  ???? */
        __wait_event(wq, condition);        \
} while (0)


Regards
Alexey Shinkin

_________________________________________________________________
Don't just search. Find. Check out the new MSN Search! 
http://search.msn.com/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: questions on wait_event ...
  2005-12-23  0:51   ` Alexey Shinkin
@ 2005-12-23  1:10     ` Steven Rostedt
  2005-12-23  1:46       ` Alexey Shinkin
  0 siblings, 1 reply; 6+ messages in thread
From: Steven Rostedt @ 2005-12-23  1:10 UTC (permalink / raw)
  To: Alexey Shinkin; +Cc: linux-kernel

On Fri, 2005-12-23 at 06:51 +0600, Alexey Shinkin wrote:

> 
> And what if the condition have changed after we have checked it in 
> wait_event() but
> before calling __wait_event() and before putting the process into the wait 
> queue ?
> The process could not be woken up "in advance" , right ?

Lets add the other part of this too (the __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;                                 \
>    /* and here we have condition changed  ???? */
>         __wait_event(wq, condition);        \
> } while (0)
> 

So if the condition happens there, it will be checked again up above in
__wait_event.

-- Steve



^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: questions on wait_event ...
  2005-12-23  1:10     ` Steven Rostedt
@ 2005-12-23  1:46       ` Alexey Shinkin
  2005-12-23 20:48         ` Steven Rostedt
  0 siblings, 1 reply; 6+ messages in thread
From: Alexey Shinkin @ 2005-12-23  1:46 UTC (permalink / raw)
  To: linux-kernel


Look:

We call wait_event() , condition is FALSE at the moment  :

    do {
         if (condition)
                 break;
    /* and here we have condition changed  to TRUE  */
    /*  process is NOT in any wait queue yet  */
    /*  then  unroll     __wait_event(wq, condition);        */

     do {							DEFINE_WAIT(__wait);					for (;;) {
	prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);

          /* at this point condition is TRUE , process is in a wait queue 
and its state is
             TASK_UNINTERRUPTIBLE.   If  rescheduling happens now the 
process will asleep,
              despite of condition is  TRUE . And will not be woken up until 
next wake_up happens
              Is that correct ?  */

	if (condition)						     break;
                    schedule();
        }
   finish_wait(&wq, &__wait);
} while (0)
   /*  end of unroll __wait_event*/

} while (0)

_________________________________________________________________
Express yourself instantly with MSN Messenger! Download today it's FREE! 
http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: questions on wait_event ...
  2005-12-23  1:46       ` Alexey Shinkin
@ 2005-12-23 20:48         ` Steven Rostedt
  0 siblings, 0 replies; 6+ messages in thread
From: Steven Rostedt @ 2005-12-23 20:48 UTC (permalink / raw)
  To: Alexey Shinkin; +Cc: linux-kernel

Please include CCs of people who respond to you or you might not ever
get a response.  There's too much traffic on the LKML, your email may
get lost in the noise.

On Fri, 2005-12-23 at 07:46 +0600, Alexey Shinkin wrote:
> Look:
> 
> We call wait_event() , condition is FALSE at the moment  :
> 
>     do {
>          if (condition)
>                  break;
>     /* and here we have condition changed  to TRUE  */
>     /*  process is NOT in any wait queue yet  */
>     /*  then  unroll     __wait_event(wq, condition);        */
> 
>      do {							DEFINE_WAIT(__wait);					for (;;) {
> 	prepare_to_wait(&wq, &__wait, TASK_UNINTERRUPTIBLE);
> 
>           /* at this point condition is TRUE , process is in a wait queue 
> and its state is
>              TASK_UNINTERRUPTIBLE.   If  rescheduling happens now the 
> process will asleep,
>               despite of condition is  TRUE . And will not be woken up until 
> next wake_up happens
>               Is that correct ?  */

OHHH! Your question is about __preemption__!!!

That's a completely different story, because if a process gets
preempted, it will _not_ be taken off the runqueue even if it's state is
in TASK_UNINTERRUPTIBLE.  Otherwise, there would be lots of places in
the kernel that is broken.

from schedule in sched.c:

/* when preempted, the preempt_count gets "PREEMPT_ACTIVE"
   so the following if will not be entered */

	if (prev->state && !(preempt_count() & PREEMPT_ACTIVE)) {
		switch_count = &prev->nvcsw;
		if (unlikely((prev->state & TASK_INTERRUPTIBLE) &&
				unlikely(signal_pending(prev))))
			prev->state = TASK_RUNNING;
		else {
			if (prev->state == TASK_UNINTERRUPTIBLE)
				rq->nr_uninterruptible++;

/* Here we would have taken off the task from the runqueue
   but we don't, so the task _will_ wake up again when it is
   scheduled back in. */

			deactivate_task(prev, rq);
		}
	}

-- Steve

> 	if (condition)						     break;
>                     schedule();
>         }
>    finish_wait(&wq, &__wait);
> } while (0)
>    /*  end of unroll __wait_event*/
> 
> } while (0)
> 
> _________________________________________________________________
> Express yourself instantly with MSN Messenger! Download today it's FREE! 
> http://messenger.msn.click-url.com/go/onm00200471ave/direct/01/
> 
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2005-12-23 20:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <5mIFB-6PS-33@gated-at.bofh.it>
2005-12-23  0:16 ` questions on wait_event Robert Hancock
2005-12-23  0:51   ` Alexey Shinkin
2005-12-23  1:10     ` Steven Rostedt
2005-12-23  1:46       ` Alexey Shinkin
2005-12-23 20:48         ` Steven Rostedt
2005-12-23  0:04 Alexey Shinkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox