From cd0196f46d54aa93bc23f0e713b943ffffebf8bd Mon Sep 17 00:00:00 2001
From: Florian Fischer <florian.fischer@muhq.space>
Date: Fri, 24 Sep 2021 11:22:48 +0200
Subject: [PATCH] add more debug messages to WakeupStrategy and
 SemaphoreWorkerSleepStrategy

Also pass getWakeupCount the CallerEnvironment because this is the place
were we must change something to prevent lost wakeups when
notifying from anywhere.
---
 emper/Runtime.hpp                                  |  2 +-
 emper/WakeupStrategy.hpp                           | 14 +++++++++++---
 .../SemaphoreWorkerSleepStrategy.hpp               | 10 +++++++++-
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/emper/Runtime.hpp b/emper/Runtime.hpp
index f9b0e276..f80dfb6f 100644
--- a/emper/Runtime.hpp
+++ b/emper/Runtime.hpp
@@ -120,7 +120,7 @@ class Runtime : public Logger<LogSubsystem::RUNTI> {
 
 	template <CallerEnvironment callerEnvironment = CallerEnvironment::EMPER>
 	inline void wakeupSleepingWorkers() {
-		workerid_t wakeupCount = wakeupStrategy.getWakeupCount();
+		workerid_t wakeupCount = wakeupStrategy.getWakeupCount<callerEnvironment>();
 		if (wakeupCount) {
 			workerSleepStrategy.notifyMany<callerEnvironment>(wakeupCount);
 		}
diff --git a/emper/WakeupStrategy.hpp b/emper/WakeupStrategy.hpp
index f2c32bbb..06dcee09 100644
--- a/emper/WakeupStrategy.hpp
+++ b/emper/WakeupStrategy.hpp
@@ -4,7 +4,9 @@
 
 #include <atomic>
 #include <cassert>
+#include <iostream>
 
+#include "CallerEnvironment.hpp"
 #include "Debug.hpp"
 #include "Emper.hpp"
 #include "emper-common.h"
@@ -54,23 +56,28 @@ class WakeupStrategy : public Logger<LogSubsystem::WAKE_S> {
 		ThrottleState notified = ThrottleState::notified;
 		bool wasNotified = throttleState.compare_exchange_strong(notified, ThrottleState::waking);
 
-		// This is the working thread now
+		// This is the waking thread now
 		if (wasNotified) {
 			isWaking = true;
 		}
 
+		LOGD("can " << (wasNotified ? "" : "not ") << "wakeup");
+
 		return wasNotified;
 	}
 
+	template <CallerEnvironment callerEnvironment>
 	auto getWakeupCountThrottle() -> workerid_t {
-		// If the waking worker calls onNewWork/shouldWakeup he is clearly done waking up
+		// If the waking worker calls onNewWork->getWakeupCount he is clearly done waking up
 		if (isWaking) {
 			resetWaking();
+			LOGD("waking worker wants to wakeup others -> 1");
 			return 1;
 		}
 
 		ThrottleState pending = ThrottleState::pending;
 		bool wasPending = throttleState.compare_exchange_strong(pending, ThrottleState::notified);
+		LOGD("get wakeup count from " << callerEnvironment << " -> " << (wasPending ? 1 : 0));
 		return wasPending ? 1 : 0;
 	}
 
@@ -110,6 +117,7 @@ class WakeupStrategy : public Logger<LogSubsystem::WAKE_S> {
 		}
 	}
 
+	template <CallerEnvironment callerEnvironment>
 	auto getWakeupCount() -> workerid_t {
 		if constexpr (emper::WORKER_WAKEUP_STRATEGY == emper::WorkerWakeupStrategy::one) {
 			return 1;
@@ -118,7 +126,7 @@ class WakeupStrategy : public Logger<LogSubsystem::WAKE_S> {
 			return workerCount;
 
 		} else if constexpr (emper::WORKER_WAKEUP_STRATEGY == emper::WorkerWakeupStrategy::throttle) {
-			return getWakeupCountThrottle();
+			return getWakeupCountThrottle<callerEnvironment>();
 
 		} else {
 			ABORT("Unknown WakeStrategy");
diff --git a/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp b/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
index 0a9f6f6a..188f0152 100644
--- a/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
+++ b/emper/sleep_strategy/SemaphoreWorkerSleepStrategy.hpp
@@ -6,6 +6,7 @@
 #include <iostream>
 
 #include "CallerEnvironment.hpp"
+#include "Debug.hpp"
 #include "Worker.hpp"
 #include "emper-common.h"
 #include "emper-config.h"
@@ -34,7 +35,8 @@ auto isRuntimeTerminating() -> bool;
 
 template <class Sem>
 class AbstractSemaphoreWorkerSleepStrategy
-		: AbstractWorkerSleepStrategy<AbstractSemaphoreWorkerSleepStrategy<Sem>> {
+		: AbstractWorkerSleepStrategy<AbstractSemaphoreWorkerSleepStrategy<Sem>>,
+			Logger<LogSubsystem::SLEEP_S> {
 	const workerid_t workerCount;
 	Sem wakeupSem;
 
@@ -157,13 +159,16 @@ class AbstractSemaphoreWorkerSleepStrategy
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyOne() {
 		if (mustNotify<callerEnvironment>()) {
+			LOGD("NotifyOne from " << callerEnvironment);
 			wakeupSem.notify();
+			stats.incNotify();
 		}
 	}
 
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyMany(unsigned count) {
 		if (mustNotify<callerEnvironment>()) {
+			LOGD("NotifyMany " << count << " from " << callerEnvironment);
 			wakeupSem.notify_many(count);
 			stats.incNotify();
 			stats.addNotifications(count);
@@ -176,6 +181,7 @@ class AbstractSemaphoreWorkerSleepStrategy
 	template <CallerEnvironment callerEnvironment>
 	inline void notifyAll() {
 		if (mustNotify<callerEnvironment>()) {
+			LOGD("NotifyAll from " << callerEnvironment);
 			wakeupSem.notify_many(workerCount);
 			stats.incNotify();
 			stats.addNotifications(workerCount);
@@ -197,7 +203,9 @@ class AbstractSemaphoreWorkerSleepStrategy
 		if constexpr (useGenericNotifySpecificImpl) {
 			genericNotifySpecificSleep();
 		} else {
+			LOGD("going to sleep");
 			wakeupSem.wait();
+			LOGD("awoken");
 			stats.incWakeup();
 		}
 	}
-- 
GitLab