Problem with conditional variables in boost

Hi I think there is a problem in implementation of function: void condition_impl::notify_one() (with BOOST_HAS_MPTASKS beeing defined - apple version) in file condition.cpp There is no mutex release before leaving that function in one place: (The same problem is in fuction notify_all) //------[ BEGIN ]------------------------------------ void condition_impl::notify_one() { unsigned signals = 0; OSStatus lStatus = noErr; lStatus = safe_enter_critical_region(m_mutex, kDurationForever, m_mutex_mutex); assert(lStatus == noErr); if (m_waiting != 0) // the m_gate is already closed { if (m_blocked == 0) { lStatus = MPExitCriticalRegion(m_mutex); assert(lStatus == noErr); return; } ++m_waiting; --m_blocked; /************************************************/ /************************************************/ There is no MPExitCriticalRegion(m_mutex) here ! /************************************************/ /************************************************/ } else { lStatus = safe_wait_on_semaphore(m_gate, kDurationForever); assert(lStatus == noErr); if (m_blocked > m_gone) { if (m_gone != 0) { m_blocked -= m_gone; m_gone = 0; } signals = m_waiting = 1; --m_blocked; } else { lStatus = MPSignalSemaphore(m_gate); assert(lStatus == noErr); } /************************************************/ /************************************************/ Solution could be putting "}" here instead of after ongoing while (signals) {...} /************************************************/ /************************************************/ lStatus = MPExitCriticalRegion(m_mutex); assert(lStatus == noErr); while (signals) { lStatus = MPSignalSemaphore(m_queue); assert(lStatus == noErr); --signals; } } } //------[ END ]------------------------------------ Second problem is in file condition.hpp //------[ BEGIN ]------------------------------------ template <typename M> void do_wait(M& mutex) { /... m_impl.enter_wait(); //... lock_ops::unlock(mutex, state); /************************************************/ /************************************************/ Unlocking mutex and hanging on semaphore should be atomic operation and here it is not (notification can be lost here (becouse of switching between threads) and thread can than wait for it forever). /************************************************/ /************************************************/ m_impl.do_wait(); //... lock_ops::lock(mutex, state); //... } //------[ END ]------------------------------------ Please correct me if I am wrong :) -- Mariusz Kedzierawski M(dot)Kedzierawski@gmail.com

Hello, I'm using boost bidirectional multigraph, and i use boost::edge(src,dst,graph) but just like this it doesnt work when there is multilinks between src and dst is there a way to specifie an id of link something like boost::edge(src,dst, idlink, graph)?? thanx

On Sep 28, 2006, at 2:48 PM, Mohamed Anouar Rachdi wrote:
Hello,
I'm using boost bidirectional multigraph, and i use
boost::edge(src,dst,graph) but just like this it doesnt
work when there is multilinks between src and dst
is there a way to specifie an id of link
something like
boost::edge(src,dst, idlink, graph)??
Not really. If you're using a graph type that sorts edges (e.g., multisetS), you can use "edge_range" and search through there. Otherwise, you're stuck combing through the out_edges yourself to see if there is an edge that matches your criteria. Doug

Mariusz Kedzierawski wrote:
I think there is a problem in implementation of function: void condition_impl::notify_one() (with BOOST_HAS_MPTASKS beeing defined - apple version) in file condition.cpp
Are you really still using the MPTASKS implementation? I am asking, because we have decided to drop support for it. What you see is just what remained from the original implementation. So yes, there are likely more problems, than you are pointing out. The MPTASKS simply is unmaintained currently. I have been told by the original maintainer that it is obsoleted today by the fact that pthread is generally available on Mac. But, if you are interested in maintaining a MPTASKS version you are invited to join in at the thread_rewrite list. We are restructuring the thread library to provide an easier platform dependant implementation, which will allow for multiple platform maintainers. But this will not happen before boost 1.35. 1.34 is only bug fixing, and MPTASKS is not officially supported for 1.34. (We have no regression tests running against it currently) Regards Roland

Hi
Are you really still using the MPTASKS implementation?
In fact, no :) But I work on software platform (OS20), which doesn't have conditional variables implemented. It have got only mutexes and semaphores at my hand, so when I lured into conditionals implementation in boost I saw impl. for mac based on mentioned mutexes and sems. I wanted to modify conditional.(h|cpp) to just use available synchro. primitives and got conds working.
So yes, there are likely more problems, than you are pointing out. The MPTASKS simply is unmaintained currently.
It explains where my problem had begun. From what I see, my only choice is to modify MPTASKS implementation and compare it with win implementation to avoid problems with synchronization (becouse win impl. is well tested and mainained). Thx for answer. -- Mariusz Kędzierawski M(dot)Kedzierawski@gmail.com

Mariusz Kedzierawski wrote:
But I work on software platform (OS20), which doesn't have conditional variables implemented.
What is OS20?
It have got only mutexes and semaphores at my hand, so when I lured into conditionals implementation in boost I saw impl. for mac based on mentioned mutexes and sems. I wanted to modify conditional.(h|cpp) to just use available synchro. primitives and got conds working.
If you do have a pthread library, I recommend using this instead, since the implementation of condition variables contains a lot of traps. Roland

Hi
What is OS20?
Its operating system from STMicroelectronics designed & implemented for their chips.
If you do have a pthread library, I recommend using this instead, since the implementation of condition variables contains a lot of traps.
Unefortunatelly I don't have pthreads on OS20. I know implementation of synchronizing primitives is very tricky, thats why I haven't started to write one by myself. I picked up boost code which I assume is well designed/implemented/tested. I just have to replace mutex/sem calls to that I have on os20. But traps you are talking about means that boost implementation for example for win is not error free and have well known flaws ? :) While analyzing conditionals impl. for win I found myself with more questions: Like I said earlier, unlocking a mutex and hanging on sem should be atomic. In template <typename M> void condition::do_wait(M& mutex).... however it is not. Doesn't that mean that we can miss notification between lock_ops::unlock(mutex, state); and m_impl.do_wait(); and possibly lock forever on sem ? I must admit that I don't fully understand all code from conditional.cpp. Its somewhat twisted, especially m_gone var. usage for example in function: void condition_impl::do_wait() there is a line: else if (++m_gone == ((std::numeric_limits<unsigned>::max)() / 2)) which checks if m_gone reached halfway to unsigned max value... Another question: since m_gone is handled in non timed waiting routine: do_wait() does it mean that I can use on single conditional object both: timed and infinitive waiting and it just works ? On OS20 for example there are separate mutex/sem object types for timed/inf. waiting. -- Mariusz Kędzierawski M(dot)Kedzierawski@gmail.com
participants (4)
-
Doug Gregor
-
Mariusz Kedzierawski
-
Mohamed Anouar Rachdi
-
Roland Schwarz