mirror of
https://github.com/esphome/esphome.git
synced 2025-10-30 14:43:51 +00:00
211739bba005d494354d9a6fcb061f26b7991059
The current implementation uses only memory_order_relaxed on all atomic
accesses. That protects each variable individually but not the semantic
link between the low word (last_millis_) and the high-word epoch counter
(millis_major_). On a multi-core target a reader could observe a freshly
stored low word before seeing the matching increment of the epoch,
causing a ~49-day negative jump.
Key fixes
- Release/acquire pairing
- writer: compare_exchange_weak(..., memory_order_release, …)
- reader: first load of last_millis_ now uses memory_order_acquire
- ensures any core that sees the new low word also sees the updated
high word
- Epoch-coherency retry loop
- re-loads millis_major_ after the update and retries if it changed,
guaranteeing monotonicity even when another core rolls over
concurrently
- millis_major_ promoted to std::atomic<uint16_t> on SMP platforms
- removes the formal data race at negligible cost
- new macros for better readability
- ESPHOME_SINGLE_CORE – currently ESP8266/RP2040 only
- ESPHOME_ATOMIC_SCHEDULER – all others except LibreTiny
- Logging and comments
- loads atomics safely in debug output
- updated inline docs to match the memory ordering
Behavior on single-core or non-atomic platforms is unchanged; multi-core
targets now get a provably monotonic 64-bit millisecond clock with
minimal overhead.
Description
Languages
C++
64.8%
Python
35%
C
0.1%
