Endless loop in runtime_nrf.go: sleepTicks()
Endless loop in runtime_nrf.go: sleepTicks() function can happen for parameter d >= 0x800000 (>= 256 seconds for 32768Hz ticks) because & 0x7fffff operation will return 0 for second and following loop runs and d variable remains unchanged:
Current version:
func sleepTicks(d timeUnit) {
for d != 0 {
ticks := uint32(d) & 0x7fffff // 23 bits (to be on the safe side)
rtc_sleep(ticks)
d -= timeUnit(ticks)
}
}
Fixed version:
func sleepTicks(d timeUnit) {
for d != 0 {
ticks := uint32(d)
if ticks > 0x7fffff { // 23 bits (to be on the safe side)
ticks = 0x7fffff
}
rtc_sleep(ticks)
d -= timeUnit(ticks)
}
}
Ugh, you are correct (I wrote this code). And I think there is a lot more code like this that is broken in the same way. Feel free to make a PR :)
@temnok @aykevl is this issue still valid?
@deadprogram Yes that's still an issue since the code did not change at https://github.com/tinygo-org/tinygo/blob/release/src/runtime/runtime_nrf.go#L80
@temnok can you check whether https://github.com/tinygo-org/tinygo/pull/5056 works for you?
(Note that the fix you proposed is also subtly wrong, since it would still ignore all the bits beyond the lower 32 - though at a 32768Hz clock that would be something like 1.5 day so less likely to hit in practice).