2004-10-13 14:22:47

by Martijn Sipkema

[permalink] [raw]
Subject: waiting on a condition

L.S.

I'd like to do something similar as can be done using a POSIX condition
variable in the kernel, i.e. wait for some condition to become true. The
pthread_cond_wait() function allows atomically unlocking a mutex and
waiting on a condition. I think I should do something like:
(the condition is updated from an interrupt handler)

disable interrupts
acquire spinlock
if condition not satisfied
add task to wait queue
set task to sleep
release spinlock
restore interrupts
schedule

Now, this will only work with preemption disabled within the critical
section. How would something like this be done whith preemption
enabled?


--ms





2004-10-13 14:57:21

by Neil Horman

[permalink] [raw]
Subject: Re: waiting on a condition

Martijn Sipkema wrote:
> L.S.
>
> I'd like to do something similar as can be done using a POSIX condition
> variable in the kernel, i.e. wait for some condition to become true. The
> pthread_cond_wait() function allows atomically unlocking a mutex and
> waiting on a condition. I think I should do something like:
> (the condition is updated from an interrupt handler)
>
> disable interrupts
> acquire spinlock
> if condition not satisfied
> add task to wait queue
> set task to sleep
> release spinlock
> restore interrupts
> schedule
>
> Now, this will only work with preemption disabled within the critical
> section. How would something like this be done whith preemption
> enabled?
>
you above algorithm seems rather prone to deadlock. Everything else in
the kernel does more or less this operation by using a wait queue and a
call to schedule to make tasks sleep until an event is signaled with a
call to one of the wake_up family of functions. Then a spinlock is used
to protect any critical data regions in smp environments. Search the
kernel for calls to add_wait_queue and wake_up[_interruptible] for
examples of how this is implemented.

HTH
Neil

>
> --ms
>
>
>
>
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to [email protected]
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/


--
/***************************************************
*Neil Horman
*Software Engineer
*Red Hat, Inc.
*[email protected]
*gpg keyid: 1024D / 0x92A74FA1
*http://pgp.mit.edu
***************************************************/

2004-10-13 15:07:52

by Duncan Sands

[permalink] [raw]
Subject: Re: waiting on a condition

You may want to look at include/linux/completion.h

Ciao,

Duncan.

2004-10-13 15:30:14

by Peter W. Morreale

[permalink] [raw]
Subject: Re: waiting on a condition

Have you looked at the wait_event() family yet? Adapting that
methodolgy might
suit your needs.

I don't know much about preemption yet, however I suspect it would be a
bug to allow
preemption while the spinlock was held. In other words, you might need
to do something like

disable preemption
spinlock
rc = condition
spin_unlock
enable preemption
if (rc)
...

In other words, perform the test on the condition outside of the
critical region protected by the spin lock.

-PWM


Martijn Sipkema wrote:

>L.S.
>
>I'd like to do something similar as can be done using a POSIX condition
>variable in the kernel, i.e. wait for some condition to become true. The
>pthread_cond_wait() function allows atomically unlocking a mutex and
>waiting on a condition. I think I should do something like:
>(the condition is updated from an interrupt handler)
>
>disable interrupts
>acquire spinlock
>if condition not satisfied
> add task to wait queue
> set task to sleep
>release spinlock
>restore interrupts
>schedule
>
>Now, this will only work with preemption disabled within the critical
>section. How would something like this be done whith preemption
>enabled?
>
>
>--ms
>
>
>
>
>-
>To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
>the body of a message to [email protected]
>More majordomo info at http://vger.kernel.org/majordomo-info.html
>Please read the FAQ at http://www.tux.org/lkml/
>
>
>

--
Peter W. Morreale email: [email protected]
Director of Engineering Niwot, Colorado, USA
Radiant Data Corporation voice: (303) 652-0870 x108
-----------------------------------------------------------------------------
This transmission may contain information that is privileged, confidential
and/or exempt from disclosure under applicable law. If you are not the
intended recipient, you are hereby notified that any disclosure, copying,
distribution, or use of the information contained herein (including any
reliance thereon) is STRICTLY PROHIBITED. If you received this transmission
in error, please immediately contact the sender and destroy the material in
its entirety, whether in electronic or hard copy format. Thank you.



2004-10-13 15:39:40

by Christophe Saout

[permalink] [raw]
Subject: Re: waiting on a condition

Am Mittwoch, den 13.10.2004, 16:23 +0100 schrieb Martijn Sipkema:

> I'd like to do something similar as can be done using a POSIX condition
> variable in the kernel, i.e. wait for some condition to become true. The
> pthread_cond_wait() function allows atomically unlocking a mutex and
> waiting on a condition. I think I should do something like:
> (the condition is updated from an interrupt handler)

You can take a look at reiser4, it has such an implementation. It's
called kcond (fs/reiser4/kcond.c). It's using semaphores, waitqueues and
a spinlock to emulate POSIX conditions.


Attachments:
signature.asc (189.00 B)
Dies ist ein digital signierter Nachrichtenteil

2004-10-13 19:00:22

by Martijn Sipkema

[permalink] [raw]
Subject: Re: waiting on a condition

On Wed, 2004-10-13 at 17:30, Peter W. Morreale wrote:
> Have you looked at the wait_event() family yet? Adapting that
> methodolgy might
> suit your needs.

wait_event() seems to be what I was looking for; I don't really like the
condition being an argument.

> I don't know much about preemption yet, however I suspect it would be a
> bug to allow
> preemption while the spinlock was held. In other words, you might need
> to do something like
>
> disable preemption
> spinlock
> rc = condition
> spin_unlock
> enable preemption
> if (rc)
> ...
>
> In other words, perform the test on the condition outside of the
> critical region protected by the spin lock.

Well, that wasn't what I meant exactly. I was looking for a standard
way to wait on a condition so that it would still work when spinlocks
are converted to mutexes such as these new RT patches seem to do;
wait_event() seens to provide this, although I like to POSIX mutex/cond
semantics better.


--ms


P.S. I seem to have been removed from the LKML right after posting
my question (it was the last message I received). Is there something
terribly stupid I may have done? Was the question _that_ stupid?



> -PWM
>
>
> Martijn Sipkema wrote:
>
> >L.S.
> >
> >I'd like to do something similar as can be done using a POSIX condition
> >variable in the kernel, i.e. wait for some condition to become true. The
> >pthread_cond_wait() function allows atomically unlocking a mutex and
> >waiting on a condition. I think I should do something like:
> >(the condition is updated from an interrupt handler)
> >
> >disable interrupts
> >acquire spinlock
> >if condition not satisfied
> > add task to wait queue
> > set task to sleep
> >release spinlock
> >restore interrupts
> >schedule
> >
> >Now, this will only work with preemption disabled within the critical
> >section. How would something like this be done whith preemption
> >enabled?
> >
> >
> >--ms
> >
> >
> >
> >
> >-
> >To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> >the body of a message to [email protected]
> >More majordomo info at http://vger.kernel.org/majordomo-info.html
> >Please read the FAQ at http://www.tux.org/lkml/
> >
> >
> >

2004-10-13 19:02:49

by Martijn Sipkema

[permalink] [raw]
Subject: Re: waiting on a condition

On Wed, 2004-10-13 at 17:30, Peter W. Morreale wrote:
> Have you looked at the wait_event() family yet? Adapting that
> methodolgy might
> suit your needs.

wait_event() seems to be what I was looking for; I don't really like the
condition being an argument.

> I don't know much about preemption yet, however I suspect it would be a
> bug to allow
> preemption while the spinlock was held. In other words, you might need
> to do something like
>
> disable preemption
> spinlock
> rc = condition
> spin_unlock
> enable preemption
> if (rc)
> ...
>
> In other words, perform the test on the condition outside of the
> critical region protected by the spin lock.

Well, that wasn't what I meant exactly. I was looking for a standard
way to wait on a condition so that it would still work when spinlocks
are converted to mutexes such as these new RT patches seem to do;
wait_event() seens to provide this, although I like to POSIX mutex/cond
semantics better.


--ms


P.S. I seem to have been removed from the LKML right after posting
my question (it was the last message I received). Is there something
terribly stupid I may have done? Was the question _that_ stupid?



> -PWM
>
>
> Martijn Sipkema wrote:
>
> >L.S.
> >
> >I'd like to do something similar as can be done using a POSIX condition
> >variable in the kernel, i.e. wait for some condition to become true. The
> >pthread_cond_wait() function allows atomically unlocking a mutex and
> >waiting on a condition. I think I should do something like:
> >(the condition is updated from an interrupt handler)
> >
> >disable interrupts
> >acquire spinlock
> >if condition not satisfied
> > add task to wait queue
> > set task to sleep
> >release spinlock
> >restore interrupts
> >schedule
> >
> >Now, this will only work with preemption disabled within the critical
> >section. How would something like this be done whith preemption
> >enabled?
> >
> >
> >--ms
> >
> >
> >
> >
> >-
> >To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> >the body of a message to [email protected]
> >More majordomo info at http://vger.kernel.org/majordomo-info.html
> >Please read the FAQ at http://www.tux.org/lkml/
> >
> >
> >

2004-10-14 15:37:17

by Davide Rossetti

[permalink] [raw]
Subject: Re: waiting on a condition

Martijn Sipkema wrote:

>On Wed, 2004-10-13 at 17:30, Peter W. Morreale wrote:
>
>
>>Have you looked at the wait_event() family yet? Adapting that
>>methodolgy might
>>suit your needs.
>>
>>
>
>wait_event() seems to be what I was looking for; I don't really like the
>condition being an argument.
>
>
>
you may have a look at http://lwn.net/Articles/22913/
it's interesting :)
regards

2004-10-14 15:49:17

by Richard B. Johnson

[permalink] [raw]
Subject: Re: waiting on a condition

On Thu, 14 Oct 2004, Davide Rossetti wrote:

> Martijn Sipkema wrote:
>
> >On Wed, 2004-10-13 at 17:30, Peter W. Morreale wrote:
> >
> >
> >>Have you looked at the wait_event() family yet? Adapting that
> >>methodolgy might
> >>suit your needs.
> >>
> >>
> >
> >wait_event() seems to be what I was looking for; I don't really like the
> >condition being an argument.
> >
> >
> >
> you may have a look at http://lwn.net/Articles/22913/
> it's interesting :)
> regards


You could always do:

while(whatever)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(0);
if(signal_pending(current))
break; // Or do something else
}
set_current_state(TASK_RUNNING); // Probably redundant

You could also set a specific HZ for the timeout, and count
them for a "never happened" timeout.




Cheers,
Dick Johnson
Penguin : Linux version 2.4.26 on an i686 machine (5570.56 BogoMips).
Note 96.31% of all statistics are fiction.

2004-10-15 14:16:32

by Alan

[permalink] [raw]
Subject: Re: waiting on a condition

On Mer, 2004-10-13 at 21:58, Martijn Sipkema wrote:
> wait_event() seems to be what I was looking for; I don't really like the
> condition being an argument.

If you look at how it unwraps it is quite hard to do any other way.
You can always pass myfunction() as the condition which is what I do
in for example the new tty code.