From 9ff06c67352df2ff8e7f4ef5bf0b57a713f47db0 Mon Sep 17 00:00:00 2001 From: Ayke van Laethem Date: Wed, 1 Oct 2025 11:56:18 +0200 Subject: [PATCH] runtime: fix sleep duration for long sleeps Long sleep durations weren't implemented correctly, by simply casting to a smaller number of bits. What we want is a saturating downcast, which is what I've used here instead. This should fix https://github.com/tinygo-org/tinygo/issues/3356. --- src/runtime/runtime_atsamd21.go | 3 +++ src/runtime/runtime_atsamd51.go | 3 +++ src/runtime/runtime_nrf.go | 3 +++ src/runtime/runtime_nrf52840.go | 3 +++ 4 files changed, 12 insertions(+) diff --git a/src/runtime/runtime_atsamd21.go b/src/runtime/runtime_atsamd21.go index e0aeb08690..52bedf739f 100644 --- a/src/runtime/runtime_atsamd21.go +++ b/src/runtime/runtime_atsamd21.go @@ -273,6 +273,9 @@ func nanosecondsToTicks(ns int64) timeUnit { func sleepTicks(d timeUnit) { for d != 0 { ticks := uint32(d) + if d > 0xffff_ffff { + ticks = 0xffff_ffff + } if !timerSleep(ticks) { // Bail out early to handle a non-time interrupt. return diff --git a/src/runtime/runtime_atsamd51.go b/src/runtime/runtime_atsamd51.go index 5c8a3d8b2f..f8d46275b5 100644 --- a/src/runtime/runtime_atsamd51.go +++ b/src/runtime/runtime_atsamd51.go @@ -266,6 +266,9 @@ func nanosecondsToTicks(ns int64) timeUnit { func sleepTicks(d timeUnit) { for d != 0 { ticks := uint32(d) + if d > 0xffff_ffff { + ticks = 0xffff_ffff + } if !timerSleep(ticks) { return } diff --git a/src/runtime/runtime_nrf.go b/src/runtime/runtime_nrf.go index a295b99669..5c992ec47b 100644 --- a/src/runtime/runtime_nrf.go +++ b/src/runtime/runtime_nrf.go @@ -78,6 +78,9 @@ func buffered() int { func sleepTicks(d timeUnit) { for d != 0 { ticks := uint32(d) & 0x7fffff // 23 bits (to be on the safe side) + if d > 0x7fffff { + ticks = 0x7fffff + } rtc_sleep(ticks) d -= timeUnit(ticks) } diff --git a/src/runtime/runtime_nrf52840.go b/src/runtime/runtime_nrf52840.go index 4ac7314a24..3c7deb031d 100644 --- a/src/runtime/runtime_nrf52840.go +++ b/src/runtime/runtime_nrf52840.go @@ -81,6 +81,9 @@ func buffered() int { func sleepTicks(d timeUnit) { for d != 0 { ticks := uint32(d) & 0x7fffff // 23 bits (to be on the safe side) + if d > 0x7fffff { + ticks = 0x7fffff + } rtc_sleep(ticks) d -= timeUnit(ticks) }