From eef7e8a3f07d86b05449b8e94a2323c796a44ef3 Mon Sep 17 00:00:00 2001 From: dragonmux Date: Mon, 29 Apr 2024 20:26:52 +0100 Subject: [PATCH] timing: Fix timeout expiration checking nearing uptime counter overflow --- src/timing.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/timing.c b/src/timing.c index 161cdbd771d..60a3c36db34 100644 --- a/src/timing.c +++ b/src/timing.c @@ -29,5 +29,17 @@ void platform_timeout_set(platform_timeout_s *const t, uint32_t ms) bool platform_timeout_is_expired(const platform_timeout_s *const t) { - return platform_time_ms() > t->time; + /* Cache the current time for the whole calculation */ + const uint32_t counter = platform_time_ms(); + /* + * Check for the tricky overflow condition and handle that properly - + * when time_ms approaches UINT32_MAX and we try to set a timeout that + * overflows to a low t->time value, if we simply compare with `<`, we will + * erroneously consider the timeout expired for a few ms right at the start of + * the valid interval. Instead, force that region of time to be considered + * not expired by checking the MSb's of the two values and handling that specially. + */ + if ((counter & UINT32_C(0x80000000)) && !(t->time & UINT32_C(0x80000000))) + return false; + return counter > t->time; }