diff --git a/emper/Runtime.cpp b/emper/Runtime.cpp index 019c26562a11187743acc2ca8703336d4691daae..b8d743cc8e73b98c984fa5a23441b8eefd70b4e3 100644 --- a/emper/Runtime.cpp +++ b/emper/Runtime.cpp @@ -66,7 +66,7 @@ Runtime::Runtime(workerid_t workerCount, RuntimeStrategy& strategy, unsigned int threads(new pthread_t[workerCount]), workers(new Worker*[workerCount]), randomEngine(seed), - atLeastOneWorkerIsSleeping(false), + sleepingWorkers(0), skipSleep(false) { const int nprocs = get_nprocs(); diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp index 8ec07545cb22bf59709ed55399b723ac52349429..c92bfc438c765c4efbc7b05eb83c14ca5462e883 100644 --- a/emper/Runtime.hpp +++ b/emper/Runtime.hpp @@ -57,7 +57,7 @@ class Runtime : public Logger<LogSubsystem::RUNTI> { ALIGN_TO_CACHE_LINE std::mutex workerSleepMutex; std::condition_variable workerSleepConditionVariable; - ALIGN_TO_CACHE_LINE std::atomic<bool> atLeastOneWorkerIsSleeping; + ALIGN_TO_CACHE_LINE std::atomic<unsigned long> sleepingWorkers; bool skipSleep; static RuntimeStrategy& DEFAULT_STRATEGY; @@ -79,15 +79,15 @@ class Runtime : public Logger<LogSubsystem::RUNTI> { // schedules another fiber, when this method will be called // again. And then it is likely that the scheduling worker will // observe the sleeping worker. - if (!atLeastOneWorkerIsSleeping.load(std::memory_order_relaxed)) { + if (!sleepingWorkers.load(std::memory_order_relaxed)) { return; } } std::lock_guard<std::mutex> lk(workerSleepMutex); skipSleep = true; - atLeastOneWorkerIsSleeping = false; - workerSleepConditionVariable.notify_all(); + sleepingWorkers.fetch_sub(1, std::memory_order_relaxed); + workerSleepConditionVariable.notify_one(); } void dispatcherLoopSleep() { @@ -100,7 +100,7 @@ class Runtime : public Logger<LogSubsystem::RUNTI> { // Check again if "skip sleep" has been set. if (skipSleep) return; - atLeastOneWorkerIsSleeping = true; + sleepingWorkers.fetch_add(1, std::memory_order_relaxed); workerSleepConditionVariable.wait(lk); }