diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp
index 1fc424eb4705ddc18d7c2832fcde05cb25308cbc..c1868e77f67aba1571b68660a4cd963acb0516a3 100644
--- a/emper/Runtime.hpp
+++ b/emper/Runtime.hpp
@@ -18,6 +18,7 @@
 #include "CallerEnvironment.hpp"
 #include "Context.hpp"
 #include "Debug.hpp"
+#include "Emper.hpp"
 #include "NextFiberResult.hpp"
 #include "Scheduler.hpp"	// for Scheduler
 #include "Worker.hpp"
@@ -96,7 +97,13 @@ class Runtime : public Logger<LogSubsystem::RUNTI> {
 
 	template <CallerEnvironment callerEnvironment = CallerEnvironment::EMPER>
 	inline void wakeupSleepingWorkers() {
-		workerSleepStrategy.notifyOne<callerEnvironment>();
+		if constexpr (::emper::WORKER_WAKEUP_STRATEGY == ::emper::WorkerWakeupStrategy::one) {
+			workerSleepStrategy.notifyOne<callerEnvironment>();
+		} else if constexpr (::emper::WORKER_WAKEUP_STRATEGY == ::emper::WorkerWakeupStrategy::all) {
+			workerSleepStrategy.notifyAll<callerEnvironment>();
+		} else {
+			ABORT("Unknown CallerEnvironment");
+		}
 	}
 
 	void maybeTerminateWorker() {
diff --git a/emper/sleep_strategy/AbstractWorkerSleepStrategy.hpp b/emper/sleep_strategy/AbstractWorkerSleepStrategy.hpp
index 335cc426f668772a70147e4d2a104516ba88d458..f0fbc4af9d8e5a6dfa227c98daed1a25b6684b09 100644
--- a/emper/sleep_strategy/AbstractWorkerSleepStrategy.hpp
+++ b/emper/sleep_strategy/AbstractWorkerSleepStrategy.hpp
@@ -5,6 +5,7 @@
 #include <stdexcept>
 
 #include "CallerEnvironment.hpp"
+#include "Emper.hpp"
 
 namespace emper::sleep_strategy {
 
diff --git a/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp b/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
index 2a81e061b894f5c47aba4643e66208036d74e632..c49439e046481b04986ef4a6f21bb56965cf7240 100644
--- a/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
+++ b/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
@@ -5,8 +5,6 @@
 #include <atomic>
 
 #include "CallerEnvironment.hpp"
-#include "Debug.hpp"
-#include "Emper.hpp"
 #include "Worker.hpp"
 #include "emper-common.h"
 #include "emper-config.h"
@@ -102,15 +100,15 @@ class AbstractSemaphoreWorkerSleepStrategy
 		}
 	}
 
-	// The actual semaphore based worker sleep algorithm
 	template <CallerEnvironment callerEnvironment>
-	void notifyInternal() {
+	[[nodiscard]] inline auto mustNotify() -> bool {
 		typename Sem::CounterType skipWakeupThreshold;
 		if constexpr (callerEnvironment == CallerEnvironment::ANYWHERE) {
 			// On external work we always increment the semaphore unless we observe
 			// that its value is > workerCount.
 			// If we observe semValue > workerCount we are ensured that some worker will iterate
 			// its dispatchLoop again and must observe the new work.
+			// TODO: Could it be >= workerCount ?
 			skipWakeupThreshold = workerCount;
 		} else {
 			// For work from within emper we skip wakeup if we observe no one sleeping.
@@ -121,40 +119,15 @@ class AbstractSemaphoreWorkerSleepStrategy
 			// Note that sem_getvalue() is allowed to return 0 if there are
 			// waiting workers, hence we need to set the threshold also to
 			// 0. This has the disadvantage that we will perform one
-			// unnecessary sem_post. If we ever switch the wakeupSem
-			// implementation, then the skipWakeupThreshold value should be
+			// unnecessary sem_post. If we are sure the wakeupSem
+			// implementation does not return 0 with waiters,
+			// then the skipWakeupThreshold value should be
 			// reviewed and potentially changed to '-1'.
 			skipWakeupThreshold = 0;
 		}
 
 		auto semValue = wakeupSem.getValue();
-		if (semValue > skipWakeupThreshold) {
-			return;
-		}
-
-		if constexpr (::emper::WORKER_WAKEUP_STRATEGY == ::emper::WorkerWakeupStrategy::one) {
-			wakeupSem.notify();
-		} else if constexpr (::emper::WORKER_WAKEUP_STRATEGY == ::emper::WorkerWakeupStrategy::all) {
-			// notify all we observed sleeping
-			// It is sound to increment the semaphore to much, thus this will only cause
-			// workers to iterate the dispatchLoop more often before actually sleeping
-
-			// TODO: Switch to c++20 std::counting_semaphore, which has release(std::ptrdiff_t)
-
-			// Reading the manpage explains the function.
-			// POSIX sem_getvalue is allowed to return 0 or a negative count if there are
-			// waiters.
-			// Linux sem_getvalue indeed does return 0
-			// To notify all sleeping workers we increment the semaphore once for each worker.
-			if (semValue == 0) {
-				semValue = workerCount;
-			}
-
-			// make sure that the amount to notify is always positive
-			wakeupSem.notify_many(semValue < 0 ? -semValue : semValue);
-		} else {
-			ABORT("Unknown CallerEnvironment");
-		}
+		return !(semValue > skipWakeupThreshold);
 	}
 
  public:
@@ -174,19 +147,26 @@ class AbstractSemaphoreWorkerSleepStrategy
 
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyOne() {
-		notifyInternal<callerEnvironment>();
+		if (mustNotify<callerEnvironment>()) {
+			wakeupSem.notify();
+		}
 	}
 
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyMany(unsigned count) {
-		for (unsigned i = 0; i < count; ++i) {
-			notifyInternal<callerEnvironment>();
+		if (mustNotify<callerEnvironment>()) {
+			wakeupSem.notify_many(count);
 		}
 	}
 
+	// notify all workers
+	// It is sound to increment the semaphore to much, thus this will only cause
+	// workers to iterate the dispatchLoop more often before actually sleeping
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyAll() {
-		notifyMany<callerEnvironment>(workerCount);
+		if (mustNotify<callerEnvironment>()) {
+			wakeupSem.notify_many(workerCount);
+		}
 	}
 
 	template <CallerEnvironment callerEnvironment>