24 #include <core/exceptions/system.h> 25 #include <core/macros.h> 26 #include <core/threading/interruptible_barrier.h> 27 #include <core/threading/mutex.h> 28 #include <core/threading/thread_list.h> 29 #include <core/threading/wait_condition.h> 34 class InterruptibleBarrierData
37 unsigned int threads_left;
39 WaitCondition *waitcond;
42 InterruptibleBarrierData(Mutex *mutex)
48 this->mutex =
new Mutex();
51 waitcond =
new WaitCondition(this->mutex);
54 ~InterruptibleBarrierData()
88 throw Exception(
"Barrier count must be at least 1");
90 data_ =
new InterruptibleBarrierData(NULL);
91 data_->threads_left = 0;
96 num_threads_in_wait_function_ = 0;
111 throw Exception(
"Barrier count must be at least 1");
113 data_ =
new InterruptibleBarrierData(mutex);
114 data_->threads_left = 0;
117 interrupted_ =
false;
119 num_threads_in_wait_function_ = 0;
129 throw Exception(
"Barriers cannot be copied");
139 throw Exception(
"Barriers cannot be copied");
147 InterruptibleBarrier &
148 InterruptibleBarrier::operator=(
const InterruptibleBarrier &b)
150 throw Exception(
"Barriers cannot be assigned");
158 InterruptibleBarrier &
159 InterruptibleBarrier::operator=(
const InterruptibleBarrier *b)
161 throw Exception(
"Barriers cannot be assigned");
179 return passed_threads_;
191 if (likely(data_->own_mutex))
192 data_->mutex->lock();
194 data_->waitcond->wake_all();
195 if (likely(data_->own_mutex))
196 data_->mutex->unlock();
207 if (likely(data_->own_mutex))
208 data_->mutex->lock();
209 interrupted_ =
false;
211 data_->threads_left =
_count;
212 passed_threads_.clear();
213 if (likely(data_->own_mutex))
214 data_->mutex->unlock();
233 if (likely(data_->own_mutex))
234 data_->mutex->lock();
235 num_threads_in_wait_function_++;
237 if (data_->threads_left == 0) {
239 timeout_ = interrupted_ = wait_at_barrier_ =
false;
240 data_->threads_left =
_count;
241 passed_threads_->clear();
243 if (interrupted_ || timeout_) {
245 num_threads_in_wait_function_--;
246 if (likely(data_->own_mutex))
247 data_->mutex->unlock();
252 --data_->threads_left;
261 bool local_timeout =
false;
264 bool waker = (data_->threads_left == 0);
266 while (data_->threads_left && !interrupted_ && !timeout_ && !local_timeout) {
269 local_timeout = !data_->waitcond->reltimed_wait(timeout_sec, timeout_nanosec);
279 if (likely(data_->own_mutex))
280 data_->mutex->unlock();
282 "%u of %u threads reached the barrier",
283 _count - data_->threads_left,
289 wait_at_barrier_ =
true;
292 if (waker || local_timeout) {
294 data_->waitcond->wake_all();
297 if (likely(data_->own_mutex))
298 data_->mutex->unlock();
300 if (wait_at_barrier_) {
305 if (likely(data_->own_mutex))
306 data_->mutex->lock();
308 num_threads_in_wait_function_--;
309 if (likely(data_->own_mutex))
310 data_->mutex->unlock();
323 if (likely(data_->own_mutex))
324 data_->mutex->lock();
325 bool res = num_threads_in_wait_function_ == 0;
326 if (likely(data_->own_mutex))
327 data_->mutex->unlock();
unsigned int count()
Get number of threads this barrier will wait for.
void interrupt()
Interrupt the barrier.
virtual void wait()
Wait for other threads.
bool no_threads_in_wait()
Checks if there are no more threads in the wait() function.
Fawkes library namespace.
virtual void wait()
Wait for other threads.
virtual ~InterruptibleBarrier()
Destructor.
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...
Base class for exceptions in Fawkes.
InterruptibleBarrier(unsigned int count)
Constructor.
unsigned int _count
Number of threads that are expected to wait for the barrier.
static Thread * current_thread()
Get the Thread instance of the currently running thread.
The current system call has been interrupted (for instance by a signal).
void print_trace()
Prints trace to stderr.
RefPtr< ThreadList > passed_threads()
Get a list of threads that passed the barrier.
RefPtr<> is a reference-counting shared smartpointer.
void reset()
Clears the barrier.
Mutex mutual exclusion lock.
A barrier is a synchronization tool which blocks until a given number of threads have reached the bar...