From c00d139e556c7231aeb5ed61cd4c9999866f5a67 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Gustaf=20Alh=C3=A4ll?= <gustaf@hanicef.me>
Date: Sat, 4 Jan 2025 20:12:00 +0100
Subject: [PATCH] Further improve sleep accuracy on UNIX systems

---
 src/sdl/i_system.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c
index 07088b9578..4d62c42875 100644
--- a/src/sdl/i_system.c
+++ b/src/sdl/i_system.c
@@ -2309,13 +2309,21 @@ void I_SleepDuration(precise_t duration)
 {
 #if defined(__linux__) || defined(__FreeBSD__) || defined(__HAIKU__)
 	UINT64 precision = I_GetPrecisePrecision();
-	struct timespec ts = {
-		.tv_sec = duration / precision,
-		.tv_nsec = duration * 1000000000 / precision % 1000000000,
-	};
-	int status;
-	do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
-	while (status == EINTR);
+	precise_t dest = I_GetPreciseTime() + duration;
+	if (duration > 100000)
+	{
+		duration -= 100000; // 0.1 ms slack
+		struct timespec ts = {
+			.tv_sec = duration / precision,
+			.tv_nsec = duration * 1000000000 / precision % 1000000000,
+		};
+		int status;
+		do status = clock_nanosleep(CLOCK_MONOTONIC, 0, &ts, &ts);
+		while (status == EINTR);
+	}
+
+	// busy-wait the rest
+	while (((INT64)dest - (INT64)I_GetPreciseTime()) > 0);
 #elif defined (MIN_SLEEP_DURATION_MS)
 	UINT64 precision = I_GetPrecisePrecision();
 	INT32 sleepvalue = cv_sleep.value;
-- 
GitLab