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;
90 InterruptibleBarrier::InterruptibleBarrier(
unsigned int count)
95 throw Exception(
"Barrier count must be at least 1");
97 __data =
new InterruptibleBarrierData(NULL);
98 __data->threads_left = 0;
101 __interrupted =
false;
119 throw Exception(
"Barrier count must be at least 1");
121 __data =
new InterruptibleBarrierData(mutex);
122 __data->threads_left = 0;
125 __interrupted =
false;
137 throw Exception(
"Barriers cannot be copied");
149 throw Exception(
"Barriers cannot be copied");
158 InterruptibleBarrier &
159 InterruptibleBarrier::operator=(
const InterruptibleBarrier &b)
161 throw Exception(
"Barriers cannot be assigned");
169 InterruptibleBarrier &
170 InterruptibleBarrier::operator=(
const InterruptibleBarrier *b)
172 throw Exception(
"Barriers cannot be assigned");
192 return __passed_threads;
205 if (likely(__data->own_mutex)) __data->mutex->lock();
206 __interrupted =
true;
207 __data->waitcond->wake_all();
208 if (likely(__data->own_mutex)) __data->mutex->unlock();
220 if (likely(__data->own_mutex)) __data->mutex->lock();
221 __interrupted =
false;
223 __data->threads_left =
_count;
224 __passed_threads.
clear();
225 if (likely(__data->own_mutex)) __data->mutex->unlock();
245 if (likely(__data->own_mutex)) __data->mutex->lock();
247 if ( __data->threads_left == 0 ) {
249 __timeout = __interrupted = __wait_at_barrier =
false;
250 __data->threads_left =
_count;
251 __passed_threads->
clear();
253 if ( __interrupted || __timeout ) {
255 if (likely(__data->own_mutex)) __data->mutex->unlock();
260 --__data->threads_left;
269 bool local_timeout =
false;
270 bool waker = (__data->threads_left == 0);
272 while ( __data->threads_left && !__interrupted && !__timeout && ! local_timeout) {
273 local_timeout = ! __data->waitcond->reltimed_wait(timeout_sec, timeout_nanosec);
275 if (local_timeout) __timeout =
true;
277 if ( __interrupted ) {
278 if (likely(__data->own_mutex)) __data->mutex->unlock();
280 "%u of %u threads reached the barrier",
284 if (waker || local_timeout) {
285 __wait_at_barrier = waker;
286 __data->waitcond->wake_all();
289 if (likely(__data->own_mutex)) __data->mutex->unlock();
291 if (__wait_at_barrier) {