Barrier.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file    Barrier.h
00006  *
00007  *  Barrier.h,v 4.10 2006/02/04 12:21:51 shuston Exp
00008  *
00009  *   Moved from Synch.h.
00010  *
00011  *  @author Douglas C. Schmidt <schmidt@cs.wustl.edu>
00012  */
00013 //==========================================================================
00014 
00015 #ifndef ACE_BARRIER_H
00016 #define ACE_BARRIER_H
00017 #include /**/ "ace/pre.h"
00018 
00019 #include "ace/ACE_export.h"
00020 
00021 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00022 # pragma once
00023 #endif /* ACE_LACKS_PRAGMA_ONCE */
00024 
00025 #include "ace/config-all.h"
00026 
00027 // ACE platform supports some form of threading.
00028 #if !defined (ACE_HAS_THREADS)
00029 
00030 #include "ace/OS_NS_errno.h"
00031 
00032 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00033 
00034 /**
00035  * @class ACE_Barrier
00036  *
00037  * @brief This is a no-op to make ACE "syntactically consistent."
00038  */
00039 class ACE_Export ACE_Barrier
00040 {
00041 public:
00042   ACE_Barrier (unsigned int, const ACE_TCHAR * = 0, void * = 0) {}
00043   ~ACE_Barrier (void) {}
00044   int wait (void) { ACE_NOTSUP_RETURN (-1); }
00045   void dump (void) const {}
00046 };
00047 
00048 ACE_END_VERSIONED_NAMESPACE_DECL
00049 
00050 #else /* ACE_HAS_THREADS */
00051 
00052 #include "ace/Condition_Thread_Mutex.h"
00053 
00054 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00055 
00056 struct ACE_Export ACE_Sub_Barrier
00057 {
00058   // = Initialization.
00059   ACE_Sub_Barrier (unsigned int count,
00060                    ACE_Thread_Mutex &lock,
00061                    const ACE_TCHAR *name = 0,
00062                    void *arg = 0);
00063 
00064   ~ACE_Sub_Barrier (void);
00065 
00066   /// True if this generation of the barrier is done.
00067   ACE_Condition_Thread_Mutex barrier_finished_;
00068 
00069   /// Number of threads that are still running.
00070   int running_threads_;
00071 
00072   /// Dump the state of an object.
00073   void dump (void) const;
00074 
00075   /// Declare the dynamic allocation hooks.
00076   ACE_ALLOC_HOOK_DECLARE;
00077 };
00078 
00079 /**
00080  * @class ACE_Barrier
00081  *
00082  * @brief Implements "barrier synchronization".
00083  *
00084  * This class allows <count> number of threads to synchronize
00085  * their completion of (one round of) a task, which is known as
00086  * "barrier synchronization".   After all the threads call <wait()>
00087  * on the barrier they are all atomically released and can begin a new
00088  * round.
00089  *
00090  * This implementation uses a "sub-barrier generation numbering"
00091  * scheme to avoid overhead and to ensure that all threads wait to
00092  * leave the barrier correct.  This code is based on an article from
00093  * SunOpsis Vol. 4, No. 1 by Richard Marejka
00094  * (Richard.Marejka@canada.sun.com).
00095  */
00096 class ACE_Export ACE_Barrier
00097 {
00098 public:
00099   /// Initialize the barrier to synchronize @a count threads.
00100   ACE_Barrier (unsigned int count,
00101                const ACE_TCHAR *name = 0,
00102                void *arg = 0);
00103 
00104   /// Default dtor.
00105   ~ACE_Barrier (void);
00106 
00107   /// Block the caller until all @c count threads have called @c wait and
00108   /// then allow all the caller threads to continue in parallel.
00109   ///
00110   /// @retval 0 after successfully waiting for all threads to wait. -1 if
00111   /// an error occurs or the barrier is shut down (@sa shutdown ()).
00112   int wait (void);
00113 
00114   /// Shut the barrier down, aborting the wait of all waiting threads.
00115   /// Any threads waiting on the barrier when it is shut down will return with
00116   /// value -1, errno ESHUTDOWN.
00117   ///
00118   /// @retval 0 for success, -1 if already shut down.
00119   ///
00120   /// @since ACE beta 5.4.9.
00121   int shutdown (void);
00122 
00123   /// Dump the state of an object.
00124   void dump (void) const;
00125 
00126   /// Declare the dynamic allocation hooks.
00127   ACE_ALLOC_HOOK_DECLARE;
00128 
00129 protected:
00130   /// Serialize access to the barrier state.
00131   ACE_Thread_Mutex lock_;
00132 
00133   /// Either 0 or 1, depending on whether we are the first generation
00134   /// of waiters or the next generation of waiters.
00135   int current_generation_;
00136 
00137   /// Total number of threads that can be waiting at any one time.
00138   int count_;
00139 
00140   /**
00141    * We keep two @c sub_barriers, one for the first "generation" of
00142    * waiters, and one for the next "generation" of waiters.  This
00143    * efficiently solves the problem of what to do if all the first
00144    * generation waiters don't leave the barrier before one of the
00145    * threads calls wait() again (i.e., starts up the next generation
00146    * barrier).
00147    */
00148   ACE_Sub_Barrier sub_barrier_1_;
00149   ACE_Sub_Barrier sub_barrier_2_;
00150   ACE_Sub_Barrier *sub_barrier_[2];
00151 
00152 private:
00153   // = Prevent assignment and initialization.
00154   void operator= (const ACE_Barrier &);
00155   ACE_Barrier (const ACE_Barrier &);
00156 };
00157 
00158 #if 0
00159 /**
00160  * @class ACE_Process_Barrier
00161  *
00162  * @brief Implements "barrier synchronization" using ACE_Process_Mutexes!
00163  *
00164  * This class is just a simple wrapper for ACE_Barrier that
00165  * selects the USYNC_PROCESS variant for the locks.
00166  */
00167 class ACE_Export ACE_Process_Barrier : public ACE_Barrier
00168 {
00169 public:
00170   /// Create a Process_Barrier, passing in the optional <name>.
00171   ACE_Process_Barrier (unsigned int count, const ACE_TCHAR *name = 0);
00172 
00173   /// Dump the state of an object.
00174   void dump (void) const;
00175 
00176   /// Declare the dynamic allocation hooks.
00177   ACE_ALLOC_HOOK_DECLARE;
00178 };
00179 #endif /* 0 */
00180 
00181 /**
00182  * @class ACE_Thread_Barrier
00183  *
00184  * @brief Implements "barrier synchronization" using ACE_Thread_Mutexes!
00185  *
00186  * This class is just a simple wrapper for ACE_Barrier that
00187  * selects the USYNC_THREAD variant for the locks.
00188  */
00189 class ACE_Export ACE_Thread_Barrier : public ACE_Barrier
00190 {
00191 public:
00192   /// Create a Thread_Barrier, passing in the optional @a name.
00193   ACE_Thread_Barrier (unsigned int count, const ACE_TCHAR *name = 0);
00194 
00195   /// Default dtor.
00196   ~ACE_Thread_Barrier (void);
00197 
00198   /// Dump the state of an object.
00199   void dump (void) const;
00200 
00201   /// Declare the dynamic allocation hooks.
00202   ACE_ALLOC_HOOK_DECLARE;
00203 };
00204 
00205 ACE_END_VERSIONED_NAMESPACE_DECL
00206 
00207 #if defined (__ACE_INLINE__)
00208 #include "ace/Barrier.inl"
00209 #endif /* __ACE_INLINE__ */
00210 
00211 #endif /* !ACE_HAS_THREADS */
00212 
00213 #include /**/ "ace/post.h"
00214 #endif /* ACE_BARRIER_H */

Generated on Thu Nov 9 09:41:47 2006 for ACE by doxygen 1.3.6