From 597fa99ff58d17dd9fb72bbc1a3dbea1fd3fbe3e Mon Sep 17 00:00:00 2001
From: Michael Eischer <eischer@cs.fau.de>
Date: Fri, 3 Jul 2020 10:56:50 +0200
Subject: [PATCH] Fix benchmark interval count jitter

As the benchmark policy and the interval statistics start at
nearly exactly the same time this could cause the interval statistics
to report one interval too much or not.

This change slightly delays to policy start and suppresses printing
of the last incomplete interval. That way the first interval captures
slightly too little data (but that doesn't matter as it's normally cut
off anyways) and the last incomplete interval only captures data
for the fraction of a second.
---
 src/refit/client/REFITBenchmark.java        | 3 +++
 src/refit/util/REFITIntervalStatistics.java | 9 ++++++++-
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/refit/client/REFITBenchmark.java b/src/refit/client/REFITBenchmark.java
index 7373d4d..d22074c 100644
--- a/src/refit/client/REFITBenchmark.java
+++ b/src/refit/client/REFITBenchmark.java
@@ -144,6 +144,9 @@ public class REFITBenchmark implements REFITStatisticsListener {
 
 		// Wait for benchmark end
 		statistics.start();
+		// Delay the policy start a bit to make it very likely that the policy completes a short time
+		// after a statistics interval result is printed
+		REFITTime.sleep(79);
 		policy.execute();
 		statistics.end();
 
diff --git a/src/refit/util/REFITIntervalStatistics.java b/src/refit/util/REFITIntervalStatistics.java
index dba947b..f30d025 100644
--- a/src/refit/util/REFITIntervalStatistics.java
+++ b/src/refit/util/REFITIntervalStatistics.java
@@ -27,6 +27,7 @@ public class REFITIntervalStatistics extends Thread {
 	private final WriterReaderPhaser eventPhaser;
 	private final AtomicBoolean firstEvent;
 
+	public int lastEpochCounter;
 	public long overallDurationInUs;
 	public int overallEventCounter;
 	public long overallEventValueAggregation;
@@ -103,7 +104,13 @@ public class REFITIntervalStatistics extends Thread {
 			long myEventValueMax = oldEvent.valueMax.get();
 			eventPhaser.readerUnlock();
 
+			// don't print incomplete last interval
+			if (!running) {
+				break;
+			}
+
 			// update overall counters
+			lastEpochCounter = myResultIndex;
 			overallEventCounter += myEventCount;
 			overallEventValueAggregation += myEventValueAggregation;
 
@@ -154,7 +161,7 @@ public class REFITIntervalStatistics extends Thread {
 		eventPhaser.flipPhase();
 		eventPhaser.readerUnlock();
 
-		listener.statisticsOverallResult(event.epochCounter - 1,
+		listener.statisticsOverallResult(lastEpochCounter,
 				overallEventCounter,
 				overallEventCounter / (float) (overallDurationInUs / (intervalInMs * 1000)),
 				overallEventValueAggregation / (float) overallEventCounter);
-- 
GitLab