mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
[rp2040] Bound the while loop in millis() accumulator
Same approach as ESP8266: split into common path (while loop, ≤10 iterations) and rare path (constant-time /1000 multiply for gaps >10 ms). RP2040 has no ISR callers so no interrupt guard needed, but the bounded loop avoids worst-case latency if millis() is called from a context that was blocked for a long time.
This commit is contained in:
@@ -26,7 +26,8 @@ void HOT yield() { ::yield(); }
|
||||
// s_last_us and ::micros() start at 0, so no special initialization needed.
|
||||
//
|
||||
// Also installed as __wrap_millis (via -Wl,--wrap=millis) so Arduino library
|
||||
// code calling ::millis() directly gets the fast version.
|
||||
// code calling ::millis() directly gets the fast version. No interrupt guard
|
||||
// needed — no ESPHome ISR calls millis() on RP2040.
|
||||
uint32_t HOT millis() {
|
||||
static struct {
|
||||
uint32_t cache;
|
||||
@@ -37,9 +38,18 @@ uint32_t HOT millis() {
|
||||
uint32_t delta = now_us - state.last_us;
|
||||
state.last_us = now_us;
|
||||
state.remainder += delta;
|
||||
while (state.remainder >= 1000) {
|
||||
state.cache++;
|
||||
state.remainder -= 1000;
|
||||
if (state.remainder >= 10000) {
|
||||
// Rare path: large gap (>10 ms — boot, long block). Constant-time
|
||||
// multiply-by-reciprocal via /1000.
|
||||
uint32_t ms = state.remainder / 1000;
|
||||
state.cache += ms;
|
||||
state.remainder -= ms * 1000;
|
||||
} else {
|
||||
// Common path: small gap. Loop runs at most 10 times.
|
||||
while (state.remainder >= 1000) {
|
||||
state.cache++;
|
||||
state.remainder -= 1000;
|
||||
}
|
||||
}
|
||||
return state.cache;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user