Moving Boost.Thread barrier from thread_dev to HEAD

The thread_dev branch in CVS contains a barrier class that I would like to move to the main branch, as has recently been requested by more than one Booster. Is anyone aware of any problems that should be addressed before this happens? For reference, see thread.hpp, http://cvs.sourceforge.net/viewcvs.py/*checkout*/boost/boost/boost/thread/Attic/barrier.hpp?content-type=text%2Fplain&rev=1.1.4.3 and thread.cpp, http://cvs.sourceforge.net/viewcvs.py/*checkout*/boost/boost/libs/thread/src/Attic/barrier.cpp?content-type=text%2Fplain&rev=1.1.4.2 One potential problem that I am aware of is that it is possible for the m_generation counter (see barrier.cpp) to overflow on systems that detect overflow of integer addition instead of wrapping (I assume there are such systems though I've never used one). Is it worthwhile checking for this and forcing wrapping in code? Mike

The thread_dev branch in CVS contains a barrier class that I would like to move to the main branch, as has recently been requested by more than one Booster. Is anyone aware of any problems that should be addressed before this happens? For reference, see
and
Would it be feasible to merge the whole thread_dev branch into the main branch? Greetings Franz Fehringer

Dr. Franz Fehringer wrote:
Would it be feasible to merge the whole thread_dev branch into the main branch?
I would like over the coming weeks to merge as much as possible of the thread_dev branch into the main branch, but I'd like to do it a bit at a time, since a) I'm not sure that all of what's there is finished, so I need to look at each piece pretty carefully before merging it, and b) I'd like to solicit comments on each of the pieces before merging them. Mike
Greetings
Franz Fehringer
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Michael Glassford <glassfordm@hotmail.com> writes:
Dr. Franz Fehringer wrote:
Would it be feasible to merge the whole thread_dev branch into the main branch?
I would like over the coming weeks to merge as much as possible of the thread_dev branch into the main branch, but I'd like to do it a bit at a time, since a) I'm not sure that all of what's there is finished, so I need to look at each piece pretty carefully before merging it, and b) I'd like to solicit comments on each of the pieces before merging them.
Mike
Mike, Thanks for taking such care with this project. -- Dave Abrahams Boost Consulting www.boost-consulting.com

Michael Glassford wrote:
One potential problem that I am aware of is that it is possible for the m_generation counter (see barrier.cpp) to overflow on systems that detect overflow of integer addition instead of wrapping (I assume there are such systems though I've never used one). Is it worthwhile checking for this and forcing wrapping in code?
I think that barrier will work just fine with a binary flag, as opposed to integer generation counter. In which case you can do flag = !flag; or m_generation = (m_generation + 1) % 2; Which would be simpler that checking for overflow on maximum integer value. It's still interesting to know if processors which trap on overflow exists nowdays... - Volodya

Vladimir Prus wrote:
Michael Glassford wrote:
One potential problem that I am aware of is that it is possible for the m_generation counter (see barrier.cpp) to overflow on systems that detect overflow of integer addition instead of wrapping (I assume there are such systems though I've never used one). Is it worthwhile checking for this and forcing wrapping in code?
I think that barrier will work just fine with a binary flag, as opposed to integer generation counter. In which case you can do
flag = !flag;
or
m_generation = (m_generation + 1) % 2;
Which would be simpler that checking for overflow on maximum integer value. It's still interesting to know if processors which trap on overflow exists nowdays...
For certain (mis)uses of the barrier class, that seems to me like it could lead to a race condition: if enough threads (re)enter the barrier before all of the threads from the previous generation finish exiting it, when the old threads wake up they will see the condition variable's condition reset to the same value as when they first entered and will wait on the conditional variable again (without first decrementing m_count, which is even worse). Theoretically this could happen with the current implementation too, but it would require a lot more threads going through the barrier!
- Volodya

Michael Glassford wrote:
m_generation = (m_generation + 1) % 2;
Which would be simpler that checking for overflow on maximum integer value. It's still interesting to know if processors which trap on overflow exists nowdays...
For certain (mis)uses of the barrier class, that seems to me like it could lead to a race condition: if enough threads (re)enter the barrier before all of the threads from the previous generation finish exiting it, when the old threads wake up they will see the condition variable's condition reset to the same value as when they first entered and will wait on the conditional variable again (without first decrementing m_count, which is even worse).
Actually, to get enough threads to reenter barrier while some threads are still inside, you need fresh threads on the next barrier. IOW, threads A, B and C wait on barrier. A gets through and spawns B' and C'. Then A, B' and C' wait on barrier, get though, and leave B and C stuck on condition wait forever. Well, I don't know if this is proper use or misuse, but anyway, if unsiged does not overflow, there's no problem to solve in the first place. - Volodya

Vladimir Prus wrote:
Michael Glassford wrote:
m_generation = (m_generation + 1) % 2;
Which would be simpler that checking for overflow on maximum integer value. It's still interesting to know if processors which trap on overflow exists nowdays...
For certain (mis)uses of the barrier class, that seems to me like it could lead to a race condition: if enough threads (re)enter the barrier before all of the threads from the previous generation finish exiting it, when the old threads wake up they will see the condition variable's condition reset to the same value as when they first entered and will wait on the conditional variable again (without first decrementing m_count, which is even worse).
Actually, to get enough threads to reenter barrier while some threads are still inside, you need fresh threads on the next barrier. IOW, threads A, B and C wait on barrier. A gets through and spawns B' and C'. Then A, B' and C' wait on barrier, get though, and leave B and C stuck on condition wait forever.
True, I realize that. Or you could simply create a barrier that blocks until it reaches, say, 5 threads and then send 10 threads through it. In a worst case scenario, 4 of the first 5 threads to wait on the barrier could get stuck there permanently. As I said, this would be a misuse of the barrier class, but it's almost certain someone will do it--and I suppose they may even have a legitimate reason for doing so.
Well, I don't know if this is proper use or misuse, but anyway, if unsiged does not overflow, there's no problem to solve in the first place.
True enough.
- Volodya
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Michael Glassford <glassfordm <at> hotmail.com> writes:
Actually, to get enough threads to reenter barrier while some threads are still inside, you need fresh threads on the next barrier. IOW, threads A, B and C wait on barrier. A gets through and spawns B' and C'. Then A, B' and C' wait on barrier, get though, and leave B and C stuck on condition wait forever.
True, I realize that. Or you could simply create a barrier that blocks until it reaches, say, 5 threads and then send 10 threads through it. In a worst case scenario, 4 of the first 5 threads to wait on the barrier could get stuck there permanently.
Is it possible to create a barrier that waits for a set of threads before permitting them to continue, rather than a count of threads? Perhaps a thread_group is a safer layer at which to implement a barrier... Matt (Adding extra lines at the end to make gmane let this through...)

Michael Glassford <glassfordm <at> hotmail.com> writes:
Actually, to get enough threads to reenter barrier while some
still inside, you need fresh threads on the next barrier. IOW,
How does it know when to release all the threads? Do you mean that you would "register" ahead of time which threads are supposed to wait, and it releases them all when they have all waited on the barrier? What would happen if an "unregistered" thread tried to wait on the barrier? Mike "Matthew Vogt" <mvogt@juptech.com> wrote in message news:loom.20040219T005359-652@post.gmane.org... threads are threads A, B
and C wait on barrier. A gets through and spawns B' and C'. Then A, B' and C' wait on barrier, get though, and leave B and C stuck on condition wait forever.
True, I realize that. Or you could simply create a barrier that blocks until it reaches, say, 5 threads and then send 10 threads through it. In a worst case scenario, 4 of the first 5 threads to wait on the barrier could get stuck there permanently.
Is it possible to create a barrier that waits for a set of threads before permitting them to continue, rather than a count of threads? Perhaps a thread_group is a safer layer at which to implement a barrier...
Matt
(Adding extra lines at the end to make gmane let this through...)
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost

Michael Glassford <glassfordm <at> hotmail.com> writes:
How does it know when to release all the threads? Do you mean that you would "register" ahead of time which threads are supposed to wait, and it releases them all when they have all waited on the barrier? What would happen if an "unregistered" thread tried to wait on the barrier?
Yes, you could use the group for registration - have a set of threads which are all in the group, and each thread in the group blocks on the barrier unless it is the last thread of the the group to reach the barrier, in which case it releases all the other threads. This would have to be a layer above pthread_barrier, I guess, and I don't think the pthread barrier would actually be used to implement it... Is there any high performance- or correctness- oriented magic in the platform's barrier implementation? If a thread that was not part of the thread group waited on the barrier, you could either throw an exception, or simply allow it to also wait until the rest of the groups threads had entered. I'm not sure how this could be worked into the syntax, though...

Matthew Vogt wrote:
Michael Glassford <glassfordm <at> hotmail.com> writes:
How does it know when to release all the threads? Do you mean that you would "register" ahead of time which threads are supposed to wait, and it releases them all when they have all waited on the barrier? What would happen if an "unregistered" thread tried to wait on the barrier?
Yes, you could use the group for registration - have a set of threads which are all in the group, and each thread in the group blocks on the barrier unless it is the last thread of the the group to reach the barrier, in which case it releases all the other threads.
I think it's interesting idea.
This would have to be a layer above pthread_barrier, I guess, and I don't think the pthread barrier would actually be used to implement it... Is there any high performance- or correctness- oriented magic in the platform's barrier implementation?
If a thread that was not part of the thread group waited on the barrier, you could either throw an exception, or simply allow it to also wait until the rest of the groups threads had entered.
I'm not sure how this could be worked into the syntax, though...
Quite easily. thread_group g; safe_barrier sb(g); // elsewhere sb.wait(); What's even more interesting, it can be implemented as wrapper on top of regular barrier: the 'wait' method would have to check that the waiting thread in in group and throw if it's not. Is it usefull? I don't know ;-) - Volodya

Vladimir Prus <ghost <at> cs.msu.su> writes:
I'm not sure how this could be worked into the syntax, though...
Quite easily.
thread_group g; safe_barrier sb(g); // elsewhere sb.wait(); What's even more interesting, it can be implemented as wrapper on top of regular barrier: the 'wait' method would have to check that the waiting thread in in group and throw if it's not.
Is it usefull? I don't know
I guess it depends on how worried you are about which threads are entering barriers. Although, if you have an app where the question of which threads are entering barriers is complex or confusing, you probably want to migrate it to dealing purely with thread_groups for everything! Matt

Michael Glassford wrote:
The thread_dev branch in CVS contains a barrier class that I would like to move to the main branch, as has recently been requested by more than one Booster.
This has now been completed.
Mike
_______________________________________________ Unsubscribe & other changes: http://lists.boost.org/mailman/listinfo.cgi/boost
participants (5)
-
David Abrahams
-
fehrin@t-online.de
-
Matthew Vogt
-
Michael Glassford
-
Vladimir Prus