Barrier.cpp

Go to the documentation of this file.
00001 // Barrier.cpp,v 4.6 2006/01/31 22:12:18 shuston Exp
00002 
00003 #include "ace/Barrier.h"
00004 
00005 #if defined (ACE_HAS_THREADS)
00006 
00007 #if !defined (__ACE_INLINE__)
00008 #include "ace/Barrier.inl"
00009 #endif /* __ACE_INLINE__ */
00010 
00011 #include "ace/Guard_T.h"
00012 #include "ace/OS_NS_errno.h"
00013 
00014 #if defined (ACE_HAS_DUMP)
00015 #  include "ace/Log_Msg.h"
00016 #endif /* ACE_HAS_DUMP */
00017 
00018 ACE_RCSID (ace,
00019            Barrier,
00020            "Barrier.cpp,v 4.6 2006/01/31 22:12:18 shuston Exp")
00021 
00022 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
00023 
00024 ACE_ALLOC_HOOK_DEFINE(ACE_Sub_Barrier)
00025 
00026 void
00027 ACE_Sub_Barrier::dump (void) const
00028 {
00029 #if defined (ACE_HAS_DUMP)
00030 // ACE_TRACE ("ACE_Sub_Barrier::dump");
00031 
00032   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00033   this->barrier_finished_.dump ();
00034   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("running_threads_ = %d"), this->running_threads_));
00035   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\n")));
00036   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00037 #endif /* ACE_HAS_DUMP */
00038 }
00039 
00040 ACE_Sub_Barrier::ACE_Sub_Barrier (unsigned int count,
00041                                   ACE_Thread_Mutex &lock,
00042                                   const ACE_TCHAR *name,
00043                                   void *arg)
00044   : barrier_finished_ (lock, name, arg),
00045     running_threads_ (count)
00046 {
00047 // ACE_TRACE ("ACE_Sub_Barrier::ACE_Sub_Barrier");
00048 }
00049 
00050 ACE_ALLOC_HOOK_DEFINE(ACE_Barrier)
00051 
00052 void
00053 ACE_Barrier::dump (void) const
00054 {
00055 #if defined (ACE_HAS_DUMP)
00056 // ACE_TRACE ("ACE_Barrier::dump");
00057 
00058   ACE_DEBUG ((LM_DEBUG, ACE_BEGIN_DUMP, this));
00059   this->lock_.dump ();
00060   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("current_generation_ = %d"), this->current_generation_));
00061   ACE_DEBUG ((LM_DEBUG, ACE_LIB_TEXT ("\ncount_ = %d"), this->count_));
00062   this->sub_barrier_1_.dump ();
00063   this->sub_barrier_2_.dump ();
00064   ACE_DEBUG ((LM_DEBUG, ACE_END_DUMP));
00065 #endif /* ACE_HAS_DUMP */
00066 }
00067 
00068 ACE_Barrier::ACE_Barrier (unsigned int count,
00069                           const ACE_TCHAR *name,
00070                           void *arg)
00071   : lock_ (name, (ACE_mutexattr_t *) arg),
00072     current_generation_ (0),
00073     count_ (count),
00074     sub_barrier_1_ (count, lock_, name, arg),
00075     sub_barrier_2_ (count, lock_, name, arg)
00076 {
00077   ACE_TRACE ("ACE_Barrier::ACE_Barrier");
00078   this->sub_barrier_[0] = &this->sub_barrier_1_;
00079   this->sub_barrier_[1] = &this->sub_barrier_2_;
00080 }
00081 
00082 int
00083 ACE_Barrier::wait (void)
00084 {
00085   ACE_TRACE ("ACE_Barrier::wait");
00086   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00087 
00088   ACE_Sub_Barrier *sbp =
00089     this->sub_barrier_[this->current_generation_];
00090 
00091   // Check for shutdown...
00092   if (sbp == 0)
00093     {
00094       errno = ESHUTDOWN;
00095       return -1;
00096     }
00097 
00098   int retval = 0;
00099 
00100   if (sbp->running_threads_ == 1)
00101     {
00102       // We're the last running thread, so swap generations and tell
00103       // all the threads waiting on the barrier to continue on their
00104       // way.
00105       sbp->running_threads_ = this->count_;
00106       // Swap generations.
00107       this->current_generation_ = 1 - this->current_generation_;
00108       sbp->barrier_finished_.broadcast ();
00109     }
00110   else
00111     {
00112       --sbp->running_threads_;
00113 
00114       // Block until all the other threads wait().
00115       while (sbp->running_threads_ != this->count_)
00116         sbp->barrier_finished_.wait ();
00117 
00118       // We're awake and the count has completed. See if it completed
00119       // because all threads hit the barrier, or because the barrier
00120       // was shut down.
00121       if (this->sub_barrier_[this->current_generation_] == 0)
00122         {
00123           errno = ESHUTDOWN;
00124           retval = -1;
00125         }
00126     }
00127 
00128   return retval;
00129 }
00130 
00131 int
00132 ACE_Barrier::shutdown (void)
00133 {
00134   ACE_TRACE ("ACE_Barrier::shutdown");
00135   ACE_GUARD_RETURN (ACE_Thread_Mutex, ace_mon, this->lock_, -1);
00136 
00137   ACE_Sub_Barrier *sbp =
00138     this->sub_barrier_[this->current_generation_];
00139 
00140   // Check for shutdown...
00141   if (sbp == 0)
00142     {
00143       errno = ESHUTDOWN;
00144       return -1;
00145     }
00146 
00147   // Flag the shutdown
00148   this->sub_barrier_[0] = 0;
00149   this->sub_barrier_[1] = 0;
00150   // Tell all the threads waiting on the barrier to continue on their way.
00151   sbp->running_threads_ = this->count_;
00152   sbp->barrier_finished_.broadcast ();
00153 
00154   return 0;
00155 }
00156 
00157 ACE_ALLOC_HOOK_DEFINE(ACE_Thread_Barrier)
00158 
00159 ACE_Thread_Barrier::ACE_Thread_Barrier (unsigned int count,
00160                                         const ACE_TCHAR *name)
00161   : ACE_Barrier (count, name)
00162 {
00163 // ACE_TRACE ("ACE_Thread_Barrier::ACE_Thread_Barrier");
00164 }
00165 
00166 void
00167 ACE_Thread_Barrier::dump (void) const
00168 {
00169 #if defined (ACE_HAS_DUMP)
00170 // ACE_TRACE ("ACE_Thread_Barrier::dump");
00171   ACE_Barrier::dump ();
00172 #endif /* ACE_HAS_DUMP */
00173 }
00174 
00175 #if 0
00176 ACE_ALLOC_HOOK_DEFINE(ACE_Process_Barrier)
00177 
00178 ACE_Process_Barrier::ACE_Process_Barrier (u_int count,
00179                                           const ACE_TCHAR *name)
00180   : ACE_Barrier (count, USYNC_PROCESS, name)
00181 {
00182 // ACE_TRACE ("ACE_Process_Barrier::ACE_Process_Barrier");
00183 }
00184 
00185 void
00186 ACE_Process_Barrier::dump (void) const
00187 {
00188 #if defined (ACE_HAS_DUMP)
00189 // ACE_TRACE ("ACE_Process_Barrier::dump");
00190   ACE_Barrier::dump ();
00191 #endif /* ACE_HAS_DUMP */
00192 }
00193 #endif /* 0 */
00194 
00195 ACE_END_VERSIONED_NAMESPACE_DECL
00196 
00197 #endif /* ACE_HAS_THREADS */

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