24 #include <core/threading/interruptible_barrier.h> 25 #include <core/threading/thread_list.h> 26 #include <core/exceptions/system.h> 27 #include <core/macros.h> 29 #include <core/threading/mutex.h> 30 #include <core/threading/wait_condition.h> 39 class InterruptibleBarrierData
42 unsigned int threads_left;
44 WaitCondition *waitcond;
47 InterruptibleBarrierData(Mutex *mutex)
53 this->mutex =
new Mutex();
56 waitcond =
new WaitCondition(this->mutex);
59 ~InterruptibleBarrierData()
61 if (own_mutex)
delete mutex;
95 throw Exception(
"Barrier count must be at least 1");
97 __data =
new InterruptibleBarrierData(NULL);
98 __data->threads_left = 0;
101 __interrupted =
false;
103 __num_threads_in_wait_function = 0;
120 throw Exception(
"Barrier count must be at least 1");
122 __data =
new InterruptibleBarrierData(mutex);
123 __data->threads_left = 0;
126 __interrupted =
false;
128 __num_threads_in_wait_function = 0;
139 throw Exception(
"Barriers cannot be copied");
151 throw Exception(
"Barriers cannot be copied");
163 throw Exception(
"Barriers cannot be assigned");
174 throw Exception(
"Barriers cannot be assigned");
194 return __passed_threads;
207 if (likely(__data->own_mutex)) __data->mutex->lock();
208 __interrupted =
true;
209 __data->waitcond->wake_all();
210 if (likely(__data->own_mutex)) __data->mutex->unlock();
222 if (likely(__data->own_mutex)) __data->mutex->lock();
223 __interrupted =
false;
225 __data->threads_left =
_count;
226 __passed_threads.clear();
227 if (likely(__data->own_mutex)) __data->mutex->unlock();
247 if (likely(__data->own_mutex)) __data->mutex->lock();
248 __num_threads_in_wait_function++;
250 if ( __data->threads_left == 0 ) {
252 __timeout = __interrupted = __wait_at_barrier =
false;
253 __data->threads_left =
_count;
254 __passed_threads->clear();
256 if ( __interrupted || __timeout ) {
258 __num_threads_in_wait_function--;
259 if (likely(__data->own_mutex)) __data->mutex->unlock();
264 --__data->threads_left;
273 bool local_timeout =
false;
276 bool waker = (__data->threads_left == 0);
278 while ( __data->threads_left && !__interrupted && !__timeout && ! local_timeout) {
281 local_timeout = ! __data->waitcond->reltimed_wait(timeout_sec, timeout_nanosec);
290 if ( __interrupted ) {
291 if (likely(__data->own_mutex)) __data->mutex->unlock();
293 "%u of %u threads reached the barrier",
299 __wait_at_barrier =
true;
302 if (waker || local_timeout) {
304 __data->waitcond->wake_all();
307 if (likely(__data->own_mutex)) __data->mutex->unlock();
309 if (__wait_at_barrier) {
314 if (likely(__data->own_mutex)) __data->mutex->lock();
316 __num_threads_in_wait_function--;
317 if (likely(__data->own_mutex)) __data->mutex->unlock();
328 if (likely(__data->own_mutex)) __data->mutex->lock();
329 bool res = __num_threads_in_wait_function == 0;
330 if (likely(__data->own_mutex)) __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...
Barrier()
Protected Constructor.
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...