[boost.thread] Atomic condition notify/mutex lock

I'm trying to find a way to atomically pulse a condition variable and acquire a mutex, something I get used to in the .Net world. It doesn't seem that this operation exists in boost/thread. Anyone has done this with boost? Thanks, Eugene

"Eugene Prystupa" <prystupa@sqlapi.com> wrote in message news:ekg9i5$826$1@sea.gmane.org...
I'm trying to find a way to atomically pulse a condition variable and acquire a mutex, something I get used to in the .Net world. It doesn't seem that this operation exists in boost/thread. Anyone has done this with boost? Thanks, Eugene
Well, you can do the condition variable stuff with an eventcount w/ waiters-bit. You can steal another bit, for the mutex. Unfortunately for you, C/C++ is a means to actually develop the synchronization primitive from pretty much scratch. C/C++ is low-level enough to interface nicely with Assembly Language. You are going to probably have to handcraft the sync, or hire a consultant that specializes in advanced multi-threading techniques. Can't you look at the source to a .Net implementation and see how they use C++ to implement their particular algorithm?

Thanks, Chris. In fact I already "hand-crafted" a primitive to do that, I was just hoping there is a publicly tested solution available. - Eugene "Chris Thomasson" <cristom@comcast.net> wrote in message news:ekgb31$e1n$1@sea.gmane.org...
"Eugene Prystupa" <prystupa@sqlapi.com> wrote in message news:ekg9i5$826$1@sea.gmane.org...
I'm trying to find a way to atomically pulse a condition variable and acquire a mutex, something I get used to in the .Net world. It doesn't seem that this operation exists in boost/thread. Anyone has done this with boost? Thanks, Eugene
Well, you can do the condition variable stuff with an eventcount w/ waiters-bit. You can steal another bit, for the mutex. Unfortunately for you, C/C++ is a means to actually develop the synchronization primitive from pretty much scratch. C/C++ is low-level enough to interface nicely with Assembly Language. You are going to probably have to handcraft the sync, or hire a consultant that specializes in advanced multi-threading techniques.
Can't you look at the source to a .Net implementation and see how they use C++ to implement their particular algorithm?
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Eugene Prystupa wrote:
I'm trying to find a way to atomically pulse a condition variable and acquire a mutex, something I get used to in the .Net world. It doesn't seem that this operation exists in boost/thread. Anyone has done this with boost? Thanks, Eugene
Why do you want to atomically pulse a condvar and acquire a mutex? What do you mean by pulse, and what do you have in mind when you say "atomically" in this context? If you acquire the mutex first, then notify/broadcast, how could your threads detect the non-atomicity of these two actions, and why are they able to?

Peter,
Why do you want to atomically pulse a condvar and acquire a mutex? What do you mean by pulse, and what do you have in mind when you say "atomically" in this context? If you acquire the mutex first, then notify/broadcast, how could your threads detect the non-atomicity of these two actions, and why are they able to?
To be precise I want to notify/broadcast one condition variable and simultaneously (atomically) start waiting on another condition variable. If I simply notify the first condition variable (and wake thread A) and then start waiting on the second condition variable (in thread B), chances are thread A may notify on the first condition before thread B starts waiting on it. P.S. I accidentally mentioned "acquiring mutex" because condition variable usage is paired with mutex in boost design. Thanks, Eugene "Peter Dimov" <pdimov@mmltd.net> wrote in message news:008d01c712e9$59aa6e50$6607a8c0@pdimov2...
Eugene Prystupa wrote:
I'm trying to find a way to atomically pulse a condition variable and acquire a mutex, something I get used to in the .Net world. It doesn't seem that this operation exists in boost/thread. Anyone has done this with boost? Thanks, Eugene
Why do you want to atomically pulse a condvar and acquire a mutex? What do you mean by pulse, and what do you have in mind when you say "atomically" in this context? If you acquire the mutex first, then notify/broadcast, how could your threads detect the non-atomicity of these two actions, and why are they able to?
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Eugene Prystupa wrote:
Peter,
Why do you want to atomically pulse a condvar and acquire a mutex? What do you mean by pulse, and what do you have in mind when you say "atomically" in this context? If you acquire the mutex first, then notify/broadcast, how could your threads detect the non-atomicity of these two actions, and why are they able to?
To be precise I want to notify/broadcast one condition variable and simultaneously (atomically) start waiting on another condition variable. If I simply notify the first condition variable (and wake thread A) and then start waiting on the second condition variable (in thread B), chances are thread A may notify on the first condition before thread B starts waiting on it.
These races typically don't occur in CV designs since a thread never waits for a CV, it waits for a condition in a while loop lock lk( mx ); while( !condition ) { cv.wait( lk ); } and it's checking the condition under the protection of mx. If the thread that modifies 'condition' also does so under the protection of mx, there are no races. You can't use a condition variable as a signalling primitive such as an event, because it maintains no state and keeps no memory of the notify/broadcast calls. So you need to keep an external predicate. Sorry if this is already clear. Maybe if you can give more information or a simple program that demonstrates what you're after, we'll be able to offer some more substantive help.

Thanks, Peter. This is an explanation I was looking for. "Peter Dimov" <pdimov@mmltd.net> wrote in message news:004e01c7135c$2bd5f670$6607a8c0@pdimov2...
Eugene Prystupa wrote:
Peter,
Why do you want to atomically pulse a condvar and acquire a mutex? What do you mean by pulse, and what do you have in mind when you say "atomically" in this context? If you acquire the mutex first, then notify/broadcast, how could your threads detect the non-atomicity of these two actions, and why are they able to?
To be precise I want to notify/broadcast one condition variable and simultaneously (atomically) start waiting on another condition variable. If I simply notify the first condition variable (and wake thread A) and then start waiting on the second condition variable (in thread B), chances are thread A may notify on the first condition before thread B starts waiting on it.
These races typically don't occur in CV designs since a thread never waits for a CV, it waits for a condition in a while loop
lock lk( mx );
while( !condition ) { cv.wait( lk ); }
and it's checking the condition under the protection of mx. If the thread that modifies 'condition' also does so under the protection of mx, there are no races.
You can't use a condition variable as a signalling primitive such as an event, because it maintains no state and keeps no memory of the notify/broadcast calls. So you need to keep an external predicate.
Sorry if this is already clear. Maybe if you can give more information or a simple program that demonstrates what you're after, we'll be able to offer some more substantive help.
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Peter Dimov wrote:
These races typically don't occur in CV designs since a thread never waits for a CV, it waits for a condition in a while loop
lock lk( mx );
while( !condition ) { cv.wait( lk ); }
and it's checking the condition under the protection of mx. If the thread that modifies 'condition' also does so under the protection of mx, there are no races.
You can't use a condition variable as a signalling primitive such as an event, because it maintains no state and keeps no memory of the notify/broadcast calls. So you need to keep an external predicate.
Is there a "reasonable" use case where a CV will not be used as you described (I mean, in a 'while' loop)? If there aren't any, then why wouldn't the CV interface be changed to do the while loop itself: template <typename Lock, typename Pred> void condition::wait(Lock &lock, Pred while_cond) { while (while_cond) { old_wait(lock); } } or something similar. Does that make sense? Yuval

On 01/12/06, Yuval Ronen <ronen_yuval@yahoo.com> wrote: <snip> If there aren't any, then why wouldn't the CV interface be changed to do the while loop itself:
template <typename Lock, typename Pred> void condition::wait(Lock &lock, Pred while_cond) { while (while_cond) { old_wait(lock); } }
or something similar.
Does that make sense?
Good sense. It is so:
#2 template<typename ScopedLock, typename Pred> void wait(ScopedLock& lock, Pred pred); Requires: ScopedLock meets the ScopedLock requirements and the return from pred() is convertible to bool. Effects: As if: while (!pred()) wait(lock) Throws: lock_error if !lock.locked() Regards, Matt.

Matt Hurd wrote:
On 01/12/06, Yuval Ronen <ronen_yuval@yahoo.com> wrote: <snip> If there aren't any, then why wouldn't the CV interface be changed to do the while loop itself:
template <typename Lock, typename Pred> void condition::wait(Lock &lock, Pred while_cond) { while (while_cond) { old_wait(lock); } }
or something similar.
Does that make sense?
Good sense. It is so:
#2 template<typename ScopedLock, typename Pred> void wait(ScopedLock& lock, Pred pred);
Requires: ScopedLock meets the ScopedLock requirements and the return from pred() is convertible to bool. Effects: As if: while (!pred()) wait(lock) Throws: lock_error if !lock.locked()
Oops, didn't notice that! Stupid me... While we're at that doc page, there's a mistake at the second timed_wait overload - it's documented to accept (ScopedLock& lock, Pred pred) while it actually accepts (ScopedLock& lock, const boost::xtime& xt, Pred pred) - the xtime parameter is missing.
participants (5)
-
Chris Thomasson
-
Eugene Prystupa
-
Matt Hurd
-
Peter Dimov
-
Yuval Ronen