From 9a255dd5f92185ba0459f265c73cf7834d956e40 Mon Sep 17 00:00:00 2001
From: Florian Schmaus <flow@cs.fau.de>
Date: Wed, 5 May 2021 17:47:08 +0200
Subject: [PATCH] [Fiber] Improve memory order of reference counter

---
 emper/Fiber.hpp | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/emper/Fiber.hpp b/emper/Fiber.hpp
index 6763e343..8fd61a78 100644
--- a/emper/Fiber.hpp
+++ b/emper/Fiber.hpp
@@ -91,15 +91,23 @@ class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> {
 		return runnable.exchange(false);
 	}
 
-	inline auto doAtomicIncrRefCount() -> unsigned int {
+	inline void doAtomicIncrRefCount() {
 		assert(referenceCounter < UINT_MAX);
 		isMulti = true;
-		return ++referenceCounter;
+		// Note: Although the first impulse is to prevent the re-ordering
+		// of the isMulti store after the reference counter modification,
+		// this *should* not be necessary. The sychronization point where
+		// this ordering is guranteed is, when the fiber is put in a
+		// concurrent queue. There the queue must gurantee that all
+		// previous stores are visible at the time the fiber appears in
+		// the queue to other threads.
+		referenceCounter.fetch_add(1, std::memory_order_relaxed);
 	}
 
 	inline auto doAtomicDecrRefCount() -> unsigned int {
 		assert(referenceCounter > 0);
-		return --referenceCounter;
+		auto previous = referenceCounter.fetch_sub(1, std::memory_order_acq_rel);
+		return previous - 1;
 	}
 
 	template <LogSubsystem>
-- 
GitLab