tinygo icon indicating copy to clipboard operation
tinygo copied to clipboard

Endless loop in runtime_nrf.go: sleepTicks()

Open temnok opened this issue 3 years ago • 4 comments

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)
	}
}

temnok avatar Dec 27 '22 01:12 temnok

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 :)

aykevl avatar Dec 30 '22 14:12 aykevl

@temnok @aykevl is this issue still valid?

deadprogram avatar Jan 13 '25 12:01 deadprogram

@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 avatar Jan 13 '25 18:01 temnok

@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).

aykevl avatar Oct 01 '25 09:10 aykevl