Address review: NMI note + static_assert hard-encoding remainder+delta overflow invariant

This commit is contained in:
J. Nick Koston
2026-04-22 07:54:11 +02:00
parent 1a23d01511
commit 12ad663723
+6 -1
View File
@@ -23,7 +23,8 @@ void HOT yield() { ::yield(); }
// Wiegand, ZyAura) also get the fast version. xt_rsil(15) guards the static
// state against ISR re-entry; the critical section is bounded (≤9 while-loop
// iterations, ~100 ns on the common path, or a constant-time /1000 ~2.5 μs on
// the rare path — well under WiFi's ~10 μs ISR latency budget).
// the rare path — well under WiFi's ~10 μs ISR latency budget). NMIs (level
// >15) are not masked, but the ESP8266 SDK's NMI handlers don't call millis().
//
// Overflow: system_get_time() wraps every ~71.6 min; unsigned now_us - last_us
// handles one wrap. Both the ESPHome main loop (1+N millis() calls per
@@ -31,6 +32,10 @@ void HOT yield() { ::yield(); }
// loop) keep state.last_us fresh well inside the 71-minute window.
static constexpr uint32_t MILLIS_RARE_PATH_THRESHOLD_US = 10000;
static constexpr uint32_t US_PER_MS = 1000;
// Guarantees state.remainder + delta cannot wrap uint32_t: the threshold caps
// remainder on entry, and delta ≤ UINT32_MAX (one system_get_time() wrap).
static_assert(MILLIS_RARE_PATH_THRESHOLD_US < UINT32_MAX / 2,
"threshold must leave headroom so remainder + delta cannot overflow uint32_t");
uint32_t IRAM_ATTR HOT millis() {
// Struct packs the three statics so the compiler loads one base address