From ca14c9df2df0c1528d47e2a03f1d00ecef401df2 Mon Sep 17 00:00:00 2001
From: psychocrypt <psychocryptHPC@gmail.com>
Date: Mon, 15 Oct 2018 11:35:06 +0200
Subject: [PATCH] reduce blocking during metric update

With #1845 a race condition during the telemetry update is solved.
The problem is that the used mutex is blocking all threads from updating the metrics during
the statistics are calculated.

- introduce a mutex per miner thread
---
 xmrstak/misc/telemetry.cpp | 10 +++++++---
 xmrstak/misc/telemetry.hpp |  2 +-
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/xmrstak/misc/telemetry.cpp b/xmrstak/misc/telemetry.cpp
index 197da8e..47442df 100644
--- a/xmrstak/misc/telemetry.cpp
+++ b/xmrstak/misc/telemetry.cpp
@@ -36,6 +36,7 @@ telemetry::telemetry(size_t iThd)
 	ppHashCounts = new uint64_t*[iThd];
 	ppTimestamps = new uint64_t*[iThd];
 	iBucketTop = new uint32_t[iThd];
+	mtx = new std::mutex[iThd];
 
 	for (size_t i = 0; i < iThd; i++)
 	{
@@ -49,8 +50,7 @@ telemetry::telemetry(size_t iThd)
 
 double telemetry::calc_telemetry_data(size_t iLastMillisec, size_t iThread)
 {
-	std::unique_lock<std::mutex> lk(mtx);
-	uint64_t iTimeNow = get_timestamp_ms();
+
 
 	uint64_t iEarliestHashCnt = 0;
 	uint64_t iEarliestStamp = 0;
@@ -58,6 +58,9 @@ double telemetry::calc_telemetry_data(size_t iLastMillisec, size_t iThread)
 	uint64_t iLatestHashCnt = 0;
 	bool bHaveFullSet = false;
 
+	std::unique_lock<std::mutex> lk(mtx[iThread]);
+	uint64_t iTimeNow = get_timestamp_ms();
+
 	//Start at 1, buckettop points to next empty
 	for (size_t i = 1; i < iBucketSize; i++)
 	{
@@ -81,6 +84,7 @@ double telemetry::calc_telemetry_data(size_t iLastMillisec, size_t iThread)
 		iEarliestStamp = ppTimestamps[iThread][idx];
 		iEarliestHashCnt = ppHashCounts[iThread][idx];
 	}
+	lk.unlock();
 
 	if (!bHaveFullSet || iEarliestStamp == 0 || iLatestStamp == 0)
 		return nan("");
@@ -99,7 +103,7 @@ double telemetry::calc_telemetry_data(size_t iLastMillisec, size_t iThread)
 
 void telemetry::push_perf_value(size_t iThd, uint64_t iHashCount, uint64_t iTimestamp)
 {
-	std::unique_lock<std::mutex> lk(mtx);
+	std::unique_lock<std::mutex> lk(mtx[iThd]);
 	size_t iTop = iBucketTop[iThd];
 	ppHashCounts[iThd][iTop] = iHashCount;
 	ppTimestamps[iThd][iTop] = iTimestamp;
diff --git a/xmrstak/misc/telemetry.hpp b/xmrstak/misc/telemetry.hpp
index 1813c00..580565d 100644
--- a/xmrstak/misc/telemetry.hpp
+++ b/xmrstak/misc/telemetry.hpp
@@ -15,7 +15,7 @@ public:
 	double calc_telemetry_data(size_t iLastMillisec, size_t iThread);
 
 private:
-	mutable std::mutex mtx;
+	std::mutex* mtx;
 	constexpr static size_t iBucketSize = 2 << 11; //Power of 2 to simplify calculations
 	constexpr static size_t iBucketMask = iBucketSize - 1;
 	uint32_t* iBucketTop;
-- 
GitLab