#include <Synch.h>
Inheritance diagram for ACE_Barrier:


Public Methods | |
| ACE_Barrier (u_int count, const ACE_TCHAR *name=0, void *arg=0) | |
| Initialize the barrier to synchronize <count> threads. More... | |
| ~ACE_Barrier (void) | |
| Default dtor. More... | |
| int | wait (void) |
| Block the caller until all <count> threads have called <wait> and then allow all the caller threads to continue in parallel. More... | |
| void | dump (void) const |
| Dump the state of an object. More... | |
Public Attributes | |
| ACE_ALLOC_HOOK_DECLARE | |
| Declare the dynamic allocation hooks. More... | |
Protected Attributes | |
| ACE_Thread_Mutex | lock_ |
| Serialize access to the barrier state. More... | |
| int | current_generation_ |
| Either 0 or 1, depending on whether we are the first generation of waiters or the next generation of waiters. More... | |
| int | count_ |
| Total number of threads that can be waiting at any one time. More... | |
| ACE_Sub_Barrier | sub_barrier_1_ |
| ACE_Sub_Barrier | sub_barrier_2_ |
| ACE_Sub_Barrier * | sub_barrier_ [2] |
Private Methods | |
| void | operator= (const ACE_Barrier &) |
| ACE_Barrier (const ACE_Barrier &) | |
This class allows <count> number of threads to synchronize their completion of (one round of) a task, which is known as "barrier synchronization". After all the threads call <wait()> on the barrier they are all atomically released and can begin a new round.
This implementation uses a "sub-barrier generation numbering" scheme to avoid overhead and to ensure that all threads wait to leave the barrier correct. This code is based on an article from SunOpsis Vol. 4, No. 1 by Richard Marejka (Richard.Marejka@canada.sun.com).
Definition at line 1556 of file Synch.h.
|
||||||||||||||||
|
Initialize the barrier to synchronize <count> threads.
Definition at line 723 of file Synch.cpp. References ACE_TCHAR, sub_barrier_, sub_barrier_1_, and sub_barrier_2_.
00726 : lock_ (name, (ACE_mutexattr_t *) arg), 00727 current_generation_ (0), 00728 count_ (count), 00729 sub_barrier_1_ (count, lock_, name, arg), 00730 sub_barrier_2_ (count, lock_, name, arg) 00731 { 00732 // ACE_TRACE ("ACE_Barrier::ACE_Barrier"); 00733 this->sub_barrier_[0] = &this->sub_barrier_1_; 00734 this->sub_barrier_[1] = &this->sub_barrier_2_; 00735 } |
|
|
Default dtor.
|
|
|
|
|
|
Dump the state of an object.
Reimplemented in ACE_Thread_Barrier. Definition at line 710 of file Synch.cpp. References ACE_BEGIN_DUMP, ACE_DEBUG, ACE_END_DUMP, ACE_LIB_TEXT, ACE_Sub_Barrier::dump, ACE_Thread_Mutex::dump, LM_DEBUG, lock_, sub_barrier_1_, and sub_barrier_2_. Referenced by ACE_Thread_Barrier::dump.
00711 {
00712 // ACE_TRACE ("ACE_Barrier::dump");
00713
00714 ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00715 this->lock_.dump ();
00716 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("current_generation_ = %d"), this->current_generation_));
00717 ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncount_ = %d"), this->count_));
00718 this->sub_barrier_1_.dump ();
00719 this->sub_barrier_2_.dump ();
00720 ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00721 }
|
|
|
|
|
|
Block the caller until all <count> threads have called <wait> and then allow all the caller threads to continue in parallel.
Definition at line 738 of file Synch.cpp. References ACE_GUARD_RETURN, ACE_Sub_Barrier::barrier_finished_, ACE_Condition_Thread_Mutex::broadcast, count_, current_generation_, ACE_Sub_Barrier::running_threads_, sub_barrier_, and ACE_Condition_Thread_Mutex::wait.
00739 {
00740 // ACE_TRACE ("ACE_Barrier::wait");
00741 ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00742
00743 ACE_Sub_Barrier *sbp =
00744 this->sub_barrier_[this->current_generation_];
00745
00746 // Check for shutdown...
00747 if (sbp == 0)
00748 return -1;
00749
00750 if (sbp->running_threads_ == 1)
00751 {
00752 // We're the last running thread, so swap generations and tell
00753 // all the threads waiting on the barrier to continue on their
00754 // way.
00755
00756 sbp->running_threads_ = this->count_;
00757 // Swap generations.
00758 this->current_generation_ = 1 - this->current_generation_;
00759 sbp->barrier_finished_.broadcast ();
00760 }
00761 else
00762 {
00763 --sbp->running_threads_;
00764
00765 // Block until all the other threads wait().
00766 while (sbp->running_threads_ != this->count_)
00767 sbp->barrier_finished_.wait ();
00768 }
00769
00770 return 0;
00771 }
|
|
|
Declare the dynamic allocation hooks.
Reimplemented in ACE_Thread_Barrier. |
|
|
Total number of threads that can be waiting at any one time.
Definition at line 1586 of file Synch.h. Referenced by wait. |
|
|
Either 0 or 1, depending on whether we are the first generation of waiters or the next generation of waiters.
Definition at line 1583 of file Synch.h. Referenced by wait. |
|
|
Serialize access to the barrier state.
Definition at line 1579 of file Synch.h. Referenced by dump. |
|
|
Definition at line 1598 of file Synch.h. Referenced by ACE_Barrier, and wait. |
|
|
We keep two <sub_barriers>, one for the first "generation" of waiters, and one for the next "generation" of waiters. This efficiently solves the problem of what to do if all the first generation waiters don't leave the barrier before one of the threads calls wait() again (i.e., starts up the next generation barrier). Definition at line 1596 of file Synch.h. Referenced by ACE_Barrier, and dump. |
|
|
Definition at line 1597 of file Synch.h. Referenced by ACE_Barrier, and dump. |
1.2.14 written by Dimitri van Heesch,
© 1997-2002