public inbox for ecos-discuss@sourceware.org
 help / color / mirror / Atom feed
* [ECOS] cyg_cond_signal() without cyg_cond_wait ()
@ 2001-08-29 13:32 Trenton D. Adams
  2001-08-30  3:45 ` Nick Garnett
  0 siblings, 1 reply; 6+ messages in thread
From: Trenton D. Adams @ 2001-08-29 13:32 UTC (permalink / raw)
  To: eCos Discussion

I've been looking through the kernel sources for answers now that I
understand a little more how eCos is laid out.

From what I've seen, it would appear that if I call cyg_cond_signal ()
while there isn't a cyg_cond_wait () in progress, nothing will happen at
all.  For example, I thought that MAYBE the condition variable would be
signaled at a later time when cyg_cond_wait () was finally called.  It
looks like cyg_cond_wait () queues the waiting threads and
cyg_cond_signal dequeues them.  But, it appears that cyg_cond_signals
are not queued, correct?

Based on that information, I should leave the condition variable's mutex
locked until such time that I can loop again to call cyg_cond_wait (),
correct?  Should I be locking the scheduler at the end of the loop until
the next loop has started?  If I don't, it's theoretically possible that
a cyg_cond_signal () could occur before I get back to my cyg_cond_wait
(), correct?

Trenton D. Adams
Extreme Engineering
#17, 6025 - 12 St. SE
Calgary, Alberta, Canada
T2H 2K1

Phone: 403 640 9494 ext-208
Fax: 403 640 9599

http://www.extremeeng.com

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

* Re: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
  2001-08-29 13:32 [ECOS] cyg_cond_signal() without cyg_cond_wait () Trenton D. Adams
@ 2001-08-30  3:45 ` Nick Garnett
  2001-08-30  8:04   ` Trenton D. Adams
  0 siblings, 1 reply; 6+ messages in thread
From: Nick Garnett @ 2001-08-30  3:45 UTC (permalink / raw)
  To: ecos-discuss

"Trenton D. Adams" <tadams@theone.dnsalias.com> writes:

> I've been looking through the kernel sources for answers now that I
> understand a little more how eCos is laid out.
> 
> From what I've seen, it would appear that if I call cyg_cond_signal ()
> while there isn't a cyg_cond_wait () in progress, nothing will happen at
> all.

Correct.

> For example, I thought that MAYBE the condition variable would be
> signaled at a later time when cyg_cond_wait () was finally called.

If that were the case, it would be a semaphore and not a condition
variable.

> It
> looks like cyg_cond_wait () queues the waiting threads and
> cyg_cond_signal dequeues them.  But, it appears that cyg_cond_signals
> are not queued, correct?

Correct.

> 
> Based on that information, I should leave the condition variable's mutex
> locked until such time that I can loop again to call cyg_cond_wait (),
> correct?

Only if you are still accessing share data protected by the mutex. If
not you should release it.

> Should I be locking the scheduler at the end of the loop until
> the next loop has started?  If I don't, it's theoretically possible that
> a cyg_cond_signal () could occur before I get back to my cyg_cond_wait
> (), correct?
> 

If you are using cyg_cond_signal() without locking the mutex, then
that can happen. That is the price you pay for not using the mutex
"correctly". If you need proper synchronization between threads, they
must use the mutex. You should not be using the scheduler lock for
this. The state of the condition variable should not be treated as a
predicate. Its state can change unilaterally at any time. The true
predicate should be in data protected by the mutex, the condition
variable is just a signalling mechanism.


-- 
Nick Garnett, eCos Kernel Architect
Red Hat, Cambridge, UK

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

* RE: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
  2001-08-30  3:45 ` Nick Garnett
@ 2001-08-30  8:04   ` Trenton D. Adams
  2001-08-30  8:20     ` Nick Garnett
  0 siblings, 1 reply; 6+ messages in thread
From: Trenton D. Adams @ 2001-08-30  8:04 UTC (permalink / raw)
  To: 'Nick Garnett', ecos-discuss

I'm not using cyg_cond_signal() without locking the mutex.  I lock the
mutex before calling cyg_cond_signal(), but this doesn't make my other
thread that's using cyg_cond_wait() get back to the cyg_cond_wait() call
before cyg_cond_signal () is called!

Here's the example you gave me.

Producer thread:
  loop indefinitely
    acquire/wait for data
    lock mutex
    copy data to buffer
    update buffer pointers
    signal condition variable
    unlock mutex

Consumer thread:
  loop indefinitely
    lock mutex
    while buffer empty
      wait for condition variable
    copy data out of buffer
    update buffer pointers
    unlock mutex
    do something with data

Now, with the example above, the producer thread could signal the
condition variable while the consumer thread is at "do something with
data".  This would cause the condition variable to never be signaled.
However, I assume that's one of the reasons for the "while buffer
empty"?  After all, it won't even bother waiting for the condition
variable again because the buffer isn't empty.

However, what happens if the acquire thread happens to be twice as fast
at getting the data as the consumer thread is at "do something with
data"?  This would cause the buffer to be filled twice in which case the
old data is now gone.


-----Original Message-----
From: ecos-discuss-owner@sources.redhat.com
[ mailto:ecos-discuss-owner@sources.redhat.com ] On Behalf Of Nick Garnett
Sent: Thursday, August 30, 2001 4:17 AM
To: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
> Should I be locking the scheduler at the end of the loop until
> the next loop has started?  If I don't, it's theoretically possible
that
> a cyg_cond_signal () could occur before I get back to my cyg_cond_wait
> (), correct?
> 

If you are using cyg_cond_signal() without locking the mutex, then
that can happen. That is the price you pay for not using the mutex
"correctly". If you need proper synchronization between threads, they
must use the mutex. You should not be using the scheduler lock for
this. The state of the condition variable should not be treated as a
predicate. Its state can change unilaterally at any time. The true
predicate should be in data protected by the mutex, the condition
variable is just a signalling mechanism.


-- 
Nick Garnett, eCos Kernel Architect
Red Hat, Cambridge, UK

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

* Re: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
  2001-08-30  8:04   ` Trenton D. Adams
@ 2001-08-30  8:20     ` Nick Garnett
  2001-08-30  8:56       ` Trenton D. Adams
  0 siblings, 1 reply; 6+ messages in thread
From: Nick Garnett @ 2001-08-30  8:20 UTC (permalink / raw)
  To: Trenton D. Adams; +Cc: ecos-discuss

"Trenton D. Adams" <tadams@theone.dnsalias.com> writes:

> I'm not using cyg_cond_signal() without locking the mutex.  I lock the
> mutex before calling cyg_cond_signal(), but this doesn't make my other
> thread that's using cyg_cond_wait() get back to the cyg_cond_wait() call
> before cyg_cond_signal () is called!
> 
> Here's the example you gave me.
> 
> Producer thread:
>   loop indefinitely
>     acquire/wait for data
>     lock mutex
>     copy data to buffer
>     update buffer pointers
>     signal condition variable
>     unlock mutex
> 
> Consumer thread:
>   loop indefinitely
>     lock mutex
>     while buffer empty
>       wait for condition variable
>     copy data out of buffer
>     update buffer pointers
>     unlock mutex
>     do something with data
> 
> Now, with the example above, the producer thread could signal the
> condition variable while the consumer thread is at "do something with
> data".  This would cause the condition variable to never be signaled.
> However, I assume that's one of the reasons for the "while buffer
> empty"?  After all, it won't even bother waiting for the condition
> variable again because the buffer isn't empty.

Exactly. The predicate that controls the behaviour of the consumer is
the "buffer empty" condition, not the state of the condition
variable. 

> 
> However, what happens if the acquire thread happens to be twice as fast
> at getting the data as the consumer thread is at "do something with
> data"?  This would cause the buffer to be filled twice in which case the
> old data is now gone.
>

OK. The above code assumed that the buffer has enough room for several
chunks of data, and that the two threads were running at approximately
the same rate, so the buffer was just being used to smooth out any
jitters in the producer. If you need to exert some flow control on the
producer, then you need something like this:

Producer thread:
  loop indefinitely
    acquire/wait for data
    lock mutex
    while buffer full
      wait for condition variable 1
    copy data to buffer
    update buffer pointers
    signal condition variable 2
    unlock mutex

Consumer thread:
  loop indefinitely
    lock mutex
    while buffer empty
      wait for condition variable 2
    copy data out of buffer
    update buffer pointers
    signal condition variable 1
    unlock mutex
    do something with data

In this case the producer is halted while the buffer is full and the
consumer while it is empty. 


-- 
Nick Garnett, eCos Kernel Architect
Red Hat, Cambridge, UK

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

* RE: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
  2001-08-30  8:20     ` Nick Garnett
@ 2001-08-30  8:56       ` Trenton D. Adams
  2001-08-30  9:04         ` Nick Garnett
  0 siblings, 1 reply; 6+ messages in thread
From: Trenton D. Adams @ 2001-08-30  8:56 UTC (permalink / raw)
  To: 'Nick Garnett'; +Cc: ecos-discuss

Ok, that makes sense.  I thought you might have to use another condition
variable, but I wasn't sure if that was good practice.  However, it
WOULD be bad practice to lock the scheduler until I'm done doing
something with the data!

My other solution of locking the mutex until the start of the next loop
would work too though right?

-----Original Message-----
From: ecos-discuss-owner@sources.redhat.com
[ mailto:ecos-discuss-owner@sources.redhat.com ] On Behalf Of Nick Garnett
Sent: Thursday, August 30, 2001 9:21 AM
To: Trenton D. Adams
Cc: ecos-discuss@sources.redhat.com
Subject: Re: [ECOS] cyg_cond_signal() without cyg_cond_wait ()


"Trenton D. Adams" <tadams@theone.dnsalias.com> writes:

> I'm not using cyg_cond_signal() without locking the mutex.  I lock the
> mutex before calling cyg_cond_signal(), but this doesn't make my other
> thread that's using cyg_cond_wait() get back to the cyg_cond_wait()
call
> before cyg_cond_signal () is called!
> 
> Here's the example you gave me.
> 
> Producer thread:
>   loop indefinitely
>     acquire/wait for data
>     lock mutex
>     copy data to buffer
>     update buffer pointers
>     signal condition variable
>     unlock mutex
> 
> Consumer thread:
>   loop indefinitely
>     lock mutex
>     while buffer empty
>       wait for condition variable
>     copy data out of buffer
>     update buffer pointers
>     unlock mutex
>     do something with data
> 
> Now, with the example above, the producer thread could signal the
> condition variable while the consumer thread is at "do something with
> data".  This would cause the condition variable to never be signaled.
> However, I assume that's one of the reasons for the "while buffer
> empty"?  After all, it won't even bother waiting for the condition
> variable again because the buffer isn't empty.

Exactly. The predicate that controls the behaviour of the consumer is
the "buffer empty" condition, not the state of the condition
variable. 

> 
> However, what happens if the acquire thread happens to be twice as
fast
> at getting the data as the consumer thread is at "do something with
> data"?  This would cause the buffer to be filled twice in which case
the
> old data is now gone.
>

OK. The above code assumed that the buffer has enough room for several
chunks of data, and that the two threads were running at approximately
the same rate, so the buffer was just being used to smooth out any
jitters in the producer. If you need to exert some flow control on the
producer, then you need something like this:

Producer thread:
  loop indefinitely
    acquire/wait for data
    lock mutex
    while buffer full
      wait for condition variable 1
    copy data to buffer
    update buffer pointers
    signal condition variable 2
    unlock mutex

Consumer thread:
  loop indefinitely
    lock mutex
    while buffer empty
      wait for condition variable 2
    copy data out of buffer
    update buffer pointers
    signal condition variable 1
    unlock mutex
    do something with data

In this case the producer is halted while the buffer is full and the
consumer while it is empty. 


-- 
Nick Garnett, eCos Kernel Architect
Red Hat, Cambridge, UK

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

* Re: [ECOS] cyg_cond_signal() without cyg_cond_wait ()
  2001-08-30  8:56       ` Trenton D. Adams
@ 2001-08-30  9:04         ` Nick Garnett
  0 siblings, 0 replies; 6+ messages in thread
From: Nick Garnett @ 2001-08-30  9:04 UTC (permalink / raw)
  To: Trenton D. Adams; +Cc: ecos-discuss

"Trenton D. Adams" <tadams@theone.dnsalias.com> writes:

> Ok, that makes sense.  I thought you might have to use another condition
> variable, but I wasn't sure if that was good practice.

Having several conditions within a single critical region is normal
practice.

> However, it
> WOULD be bad practice to lock the scheduler until I'm done doing
> something with the data!

Exactly.

> 
> My other solution of locking the mutex until the start of the next loop
> would work too though right?

Probably, but it is not something I want to seen to encourage. Mutexes
should be kept locked for the minimum period possible.


-- 
Nick Garnett, eCos Kernel Architect
Red Hat, Cambridge, UK

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

end of thread, other threads:[~2001-08-30  9:04 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-08-29 13:32 [ECOS] cyg_cond_signal() without cyg_cond_wait () Trenton D. Adams
2001-08-30  3:45 ` Nick Garnett
2001-08-30  8:04   ` Trenton D. Adams
2001-08-30  8:20     ` Nick Garnett
2001-08-30  8:56       ` Trenton D. Adams
2001-08-30  9:04         ` Nick Garnett

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).