From a448bfb194ca51667a6d8758b1487311284f27e4 Mon Sep 17 00:00:00 2001
From: Florian Schmaus <flow@cs.fau.de>
Date: Tue, 27 Jul 2021 11:55:12 +0200
Subject: [PATCH] [stats] Add max-queue-length stats to
 AbstractWorkStealingScheduler

---
 emper/lib/adt/LockedQueue.hpp                        | 5 +++++
 emper/strategies/AbstractWorkStealingScheduler.cpp   | 3 ++-
 emper/strategies/AbstractWorkStealingStats.cpp       | 2 ++
 emper/strategies/AbstractWorkStealingWorkerStats.cpp | 6 ++++++
 emper/strategies/AbstractWorkStealingWorkerStats.hpp | 3 +++
 5 files changed, 18 insertions(+), 1 deletion(-)

diff --git a/emper/lib/adt/LockedQueue.hpp b/emper/lib/adt/LockedQueue.hpp
index a1a86180..6344ccd4 100644
--- a/emper/lib/adt/LockedQueue.hpp
+++ b/emper/lib/adt/LockedQueue.hpp
@@ -29,6 +29,11 @@ class LockedQueue {
 		return SIZE - deque.size();
 	}
 
+	auto usedSlots() -> size_t {
+		std::lock_guard<std::mutex> lock(queue_mutex);
+		return deque.size();
+	}
+
 	auto pushBottom(const I item) -> bool {
 		std::lock_guard<std::mutex> lock(queue_mutex);
 
diff --git a/emper/strategies/AbstractWorkStealingScheduler.cpp b/emper/strategies/AbstractWorkStealingScheduler.cpp
index 9205a689..09fc49b8 100644
--- a/emper/strategies/AbstractWorkStealingScheduler.cpp
+++ b/emper/strategies/AbstractWorkStealingScheduler.cpp
@@ -48,7 +48,8 @@ void AbstractWorkStealingScheduler::scheduleViaWorkStealing(Fiber& fiber) {
 			ABORT("Could not push fiber " << &fiber << " into queue");
 		}
 	} else if constexpr (emper::STATS) {
-		awss::stats.scheduledFibersToLocal++;
+		uint64_t queueLength = queue.usedSlots();
+		awss::stats.recordScheduledToLocalAndQueueLength(queueLength);
 	}
 
 	// Classes using this method are supposed to always invoke this
diff --git a/emper/strategies/AbstractWorkStealingStats.cpp b/emper/strategies/AbstractWorkStealingStats.cpp
index 0e6492a2..c6e6e796 100644
--- a/emper/strategies/AbstractWorkStealingStats.cpp
+++ b/emper/strategies/AbstractWorkStealingStats.cpp
@@ -21,6 +21,8 @@ void AbstractWorkStealingStats::print() {
 						<< std::to_string(comulatedWorkerStats.scheduledFibersToLocal) << std::endl
 						<< "total-scheduled-fibers-to-overflow-queue: "
 						<< std::to_string(comulatedWorkerStats.scheduledFibersToOverflowQueue) << std::endl
+						<< "global-max-queue-length: " << std::to_string(comulatedWorkerStats.maxQueueLength)
+						<< std::endl
 						<< "total-next-fiber-from-local: "
 						<< std::to_string(comulatedWorkerStats.nextFiberFromLocal) << std::endl
 						<< "total-next-fiber-hint-local: "
diff --git a/emper/strategies/AbstractWorkStealingWorkerStats.cpp b/emper/strategies/AbstractWorkStealingWorkerStats.cpp
index 260e5d4f..c7adae3f 100644
--- a/emper/strategies/AbstractWorkStealingWorkerStats.cpp
+++ b/emper/strategies/AbstractWorkStealingWorkerStats.cpp
@@ -8,6 +8,7 @@ auto AbstractWorkStealingWorkerStats::operator+=(const AbstractWorkStealingWorke
 		-> AbstractWorkStealingWorkerStats& {
 	scheduledFibersToLocal += other.scheduledFibersToLocal;
 	scheduledFibersToOverflowQueue += other.scheduledFibersToOverflowQueue;
+	maxQueueLength = std::max(maxQueueLength, other.maxQueueLength);
 	nextFiberFromLocal += other.nextFiberFromLocal;
 	nextFiberStolen += other.nextFiberStolen;
 	nextFiberFromAnywhereQueue += other.nextFiberFromAnywhereQueue;
@@ -27,3 +28,8 @@ void AbstractWorkStealingWorkerStats::recordFibersLiftedFromAnywhereQueue(
 			std::max(maxFibersLiftedFromAnywhereQueue, fibersLiftedFromAnywhereQueue);
 	avgFibersLiftedFromAnywhereQueue.update(fibersLiftedFromAnywhereQueue);
 }
+
+void AbstractWorkStealingWorkerStats::recordScheduledToLocalAndQueueLength(uint64_t queueLength) {
+	scheduledFibersToLocal++;
+	maxQueueLength = std::max(maxQueueLength, queueLength);
+}
diff --git a/emper/strategies/AbstractWorkStealingWorkerStats.hpp b/emper/strategies/AbstractWorkStealingWorkerStats.hpp
index 35126d12..684b1d59 100644
--- a/emper/strategies/AbstractWorkStealingWorkerStats.hpp
+++ b/emper/strategies/AbstractWorkStealingWorkerStats.hpp
@@ -15,6 +15,7 @@ class AbstractWorkStealingWorkerStats {
  public:
 	uint64_t scheduledFibersToLocal = 0;
 	uint64_t scheduledFibersToOverflowQueue = 0;
+	uint64_t maxQueueLength = 0;
 	uint64_t nextFiberFromLocal = 0;
 	uint64_t nextFiberFromHintLocal = 0;
 	uint64_t nextFiberFromHintAnywhere = 0;
@@ -29,4 +30,6 @@ class AbstractWorkStealingWorkerStats {
 
  private:
 	void recordFibersLiftedFromAnywhereQueue(size_t fibersLiftedFromAnywhere);
+
+	void recordScheduledToLocalAndQueueLength(uint64_t queueLength);
 };
-- 
GitLab