Barrier.h

Go to the documentation of this file.
00001 // -*- C++ -*-
00002 
00003 //==========================================================================
00004 /**
00005  *  @file    Barrier.h
00006  *
00007  *  $Id: Barrier.h 80826 2008-03-04 14:51:23Z wotte $
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.
00111   /// @retval -1 if an error occurs or the barrier is shut
00112   /// down (@sa shutdown ()).
00113   int wait (void);
00114 
00115   /// Shut the barrier down, aborting the wait of all waiting threads.
00116   /// Any threads waiting on the barrier when it is shut down will return with
00117   /// value -1, errno ESHUTDOWN.
00118   ///
00119   /// @retval 0 for success, -1 if already shut down.
00120   ///
00121   /// @since ACE beta 5.4.9.
00122   int shutdown (void);
00123 
00124   /// Dump the state of an object.
00125   void dump (void) const;
00126 
00127   /// Declare the dynamic allocation hooks.
00128   ACE_ALLOC_HOOK_DECLARE;
00129 
00130 protected:
00131   /// Serialize access to the barrier state.
00132   ACE_Thread_Mutex lock_;
00133 
00134   /// Either 0 or 1, depending on whether we are the first generation
00135   /// of waiters or the next generation of waiters.
00136   int current_generation_;
00137 
00138   /// Total number of threads that can be waiting at any one time.
00139   int count_;
00140 
00141   /**
00142    * We keep two @c sub_barriers, one for the first "generation" of
00143    * waiters, and one for the next "generation" of waiters.  This
00144    * efficiently solves the problem of what to do if all the first
00145    * generation waiters don't leave the barrier before one of the
00146    * threads calls wait() again (i.e., starts up the next generation
00147    * barrier).
00148    */
00149   ACE_Sub_Barrier sub_barrier_1_;
00150   ACE_Sub_Barrier sub_barrier_2_;
00151   ACE_Sub_Barrier *sub_barrier_[2];
00152 
00153 private:
00154   // = Prevent assignment and initialization.
00155   void operator= (const ACE_Barrier &);
00156   ACE_Barrier (const ACE_Barrier &);
00157 };
00158 
00159 #if 0
00160 /**
00161  * @class ACE_Process_Barrier
00162  *
00163  * @brief Implements "barrier synchronization" using ACE_Process_Mutexes!
00164  *
00165  * This class is just a simple wrapper for ACE_Barrier that
00166  * selects the USYNC_PROCESS variant for the locks.
00167  */
00168 class ACE_Export ACE_Process_Barrier : public ACE_Barrier
00169 {
00170 public:
00171   /// Create a Process_Barrier, passing in the optional @a name.
00172   ACE_Process_Barrier (unsigned int count, const ACE_TCHAR *name = 0);
00173 
00174   /// Dump the state of an object.
00175   void dump (void) const;
00176 
00177   /// Declare the dynamic allocation hooks.
00178   ACE_ALLOC_HOOK_DECLARE;
00179 };
00180 #endif /* 0 */
00181 
00182 /**
00183  * @class ACE_Thread_Barrier
00184  *
00185  * @brief Implements "barrier synchronization" using ACE_Thread_Mutexes!
00186  *
00187  * This class is just a simple wrapper for ACE_Barrier that
00188  * selects the USYNC_THREAD variant for the locks.
00189  */
00190 class ACE_Export ACE_Thread_Barrier : public ACE_Barrier
00191 {
00192 public:
00193   /// Create a Thread_Barrier, passing in the optional @a name.
00194   ACE_Thread_Barrier (unsigned int count, const ACE_TCHAR *name = 0);
00195 
00196   /// Default dtor.
00197   ~ACE_Thread_Barrier (void);
00198 
00199   /// Dump the state of an object.
00200   void dump (void) const;
00201 
00202   /// Declare the dynamic allocation hooks.
00203   ACE_ALLOC_HOOK_DECLARE;
00204 };
00205 
00206 ACE_END_VERSIONED_NAMESPACE_DECL
00207 
00208 #if defined (__ACE_INLINE__)
00209 #include "ace/Barrier.inl"
00210 #endif /* __ACE_INLINE__ */
00211 
00212 #endif /* !ACE_HAS_THREADS */
00213 
00214 #include /**/ "ace/post.h"
00215 #endif /* ACE_BARRIER_H */

Generated on Tue Feb 2 17:18:38 2010 for ACE by  doxygen 1.4.7