00001
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
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
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
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
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
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
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
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
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
00103
00104
00105 sbp->running_threads_ = this->count_;
00106
00107 this->current_generation_ = 1 - this->current_generation_;
00108 sbp->barrier_finished_.broadcast ();
00109 }
00110 else
00111 {
00112 --sbp->running_threads_;
00113
00114
00115 while (sbp->running_threads_ != this->count_)
00116 sbp->barrier_finished_.wait ();
00117
00118
00119
00120
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
00141 if (sbp == 0)
00142 {
00143 errno = ESHUTDOWN;
00144 return -1;
00145 }
00146
00147
00148 this->sub_barrier_[0] = 0;
00149 this->sub_barrier_[1] = 0;
00150
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
00164 }
00165
00166 void
00167 ACE_Thread_Barrier::dump (void) const
00168 {
00169 #if defined (ACE_HAS_DUMP)
00170
00171 ACE_Barrier::dump ();
00172 #endif
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
00183 }
00184
00185 void
00186 ACE_Process_Barrier::dump (void) const
00187 {
00188 #if defined (ACE_HAS_DUMP)
00189
00190 ACE_Barrier::dump ();
00191 #endif
00192 }
00193 #endif
00194
00195 ACE_END_VERSIONED_NAMESPACE_DECL
00196
00197 #endif