From 85edba20e79cdbde5295696ecc4950f584819899 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Wed, 16 Feb 2022 18:29:30 +0100 Subject: [PATCH] Enforce deadline reached on timeout The value of sc_tick_now() has microsecond precision, but sc_cond_timedwait() has only millisecond precision. To guarantee that sc_tick_now() >= deadline when sc_cond_timedwait() returns due to timeout, round up to the next millisecond. This avoids to call a non-blocking sc_cond_timedwait() in a loop for no reason until a target deadline during up to 1 millisecond. Refs 682a6911735cb8f6dccd9653ce30b72f267235c6 --- app/src/util/thread.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/util/thread.c b/app/src/util/thread.c index 0d098b3f..478867b6 100644 --- a/app/src/util/thread.c +++ b/app/src/util/thread.c @@ -136,7 +136,9 @@ sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick deadline) { return false; // timeout } - uint32_t ms = SC_TICK_TO_MS(deadline - now); + // Round up to the next millisecond to guarantee that the deadline is + // reached when returning due to timeout + uint32_t ms = SC_TICK_TO_MS(deadline - now + SC_TICK_FROM_MS(1) - 1); int r = SDL_CondWaitTimeout(cond->cond, mutex->mutex, ms); #ifndef NDEBUG if (r < 0) { @@ -148,6 +150,8 @@ sc_cond_timedwait(sc_cond *cond, sc_mutex *mutex, sc_tick deadline) { memory_order_relaxed); #endif assert(r == 0 || r == SDL_MUTEX_TIMEDOUT); + // The deadline is reached on timeout + assert(r != SDL_MUTEX_TIMEDOUT || sc_tick_now() >= deadline); return r == 0; }