From 77c2b2f08b4380ac0137d3d6c97731067f980242 Mon Sep 17 00:00:00 2001 From: matpala Date: Tue, 13 Oct 2026 10:04:24 -0300 Subject: [PATCH 1/3] drivers: fix overflow in ClockDevice.sleep_ms --- drivers/src/base/ClockDevice.zig | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/drivers/src/base/ClockDevice.zig b/drivers/src/base/ClockDevice.zig index b9236c0d6..944b00f5b 100644 --- a/drivers/src/base/ClockDevice.zig +++ b/drivers/src/base/ClockDevice.zig @@ -46,7 +46,10 @@ pub fn make_timeout(td: ClockDevice, timeout: mdf.time.Duration) Timeout { } pub fn sleep_ms(td: ClockDevice, time_ms: u32) void { - td.sleep_us(time_ms * 1000); + // 1000 = 1024 - 16 - 8, in u64 so that it doesn't overflow. Shifts avoid + // the multiplication helpers that AVR doesn't link. + const ms: u64 = time_ms; + td.sleep_us((ms << 10) - (ms << 4) - (ms << 3)); } pub fn sleep_us(td: ClockDevice, time_us: u64) void { @@ -145,3 +148,14 @@ test TestDevice { td.sleep_ms(1000); try std.testing.expectEqual(1_000_000, ttd.get_total_sleep_time()); } + +test sleep_ms { + var ttd = TestDevice.init(); + const td = ttd.clock_device(); + + for ([_]u32{ 0, 1, 4_294_967, std.math.maxInt(u32) }) |time_ms| { + ttd.reset_sleep_time(); + td.sleep_ms(time_ms); + try std.testing.expectEqual(@as(u64, time_ms) * 1000, ttd.get_total_sleep_time()); + } +} From 31d260971c363e39a2282d5d2ba3ed9902a3a88b Mon Sep 17 00:00:00 2001 From: matpala Date: Tue, 13 Oct 2026 10:12:43 -0300 Subject: [PATCH 2/3] drivers: test the first sleep_ms value that overflowed --- drivers/src/base/ClockDevice.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/src/base/ClockDevice.zig b/drivers/src/base/ClockDevice.zig index 944b00f5b..f0aa2ecdf 100644 --- a/drivers/src/base/ClockDevice.zig +++ b/drivers/src/base/ClockDevice.zig @@ -153,7 +153,7 @@ test sleep_ms { var ttd = TestDevice.init(); const td = ttd.clock_device(); - for ([_]u32{ 0, 1, 4_294_967, std.math.maxInt(u32) }) |time_ms| { + for ([_]u32{ 0, 1, 4_294_967, 4_294_968, std.math.maxInt(u32) }) |time_ms| { ttd.reset_sleep_time(); td.sleep_ms(time_ms); try std.testing.expectEqual(@as(u64, time_ms) * 1000, ttd.get_total_sleep_time()); From cfb96b2e18b612887af799eb26c64370ffbbf024 Mon Sep 17 00:00:00 2001 From: matpala Date: Wed, 14 Oct 2026 10:22:50 -0300 Subject: [PATCH 3/3] drivers: drop the AVR note from the sleep_ms comment --- drivers/src/base/ClockDevice.zig | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/src/base/ClockDevice.zig b/drivers/src/base/ClockDevice.zig index f0aa2ecdf..5c3139c9f 100644 --- a/drivers/src/base/ClockDevice.zig +++ b/drivers/src/base/ClockDevice.zig @@ -46,8 +46,7 @@ pub fn make_timeout(td: ClockDevice, timeout: mdf.time.Duration) Timeout { } pub fn sleep_ms(td: ClockDevice, time_ms: u32) void { - // 1000 = 1024 - 16 - 8, in u64 so that it doesn't overflow. Shifts avoid - // the multiplication helpers that AVR doesn't link. + // 1000 = 1024 - 16 - 8, in u64 so that it doesn't overflow. const ms: u64 = time_ms; td.sleep_us((ms << 10) - (ms << 4) - (ms << 3)); }