mirror of
https://github.com/esphome/esphome.git
synced 2026-07-10 17:05:36 +00:00
ecbc249d7a35feacf4e58af48c5815476d8f5b89
On ESPHOME_THREAD_MULTI_NO_ATOMICS (BK72xx is the sole target — ARMv5TE,
no LDREX/STREX, so std::atomic is off), the per-helper _empty_() fast
paths fall back to "always take the lock". That means Scheduler::call()
paid a separate FreeRTOS mutex round-trip for each of:
- process_defer_queue_ (defer_empty_)
- process_to_add (to_add_empty_)
- cleanup_ (to_remove_empty_)
on every iteration, even on idle ticks where all three counters are
zero. Each round-trip is ~5-10us on BK72xx, adding ~75ms/min of
main-loop overhead at ~3100 iter/min. This matched the measured gap
between BK72xx (sched=125ms/min) and RTL87xx (sched=19ms/min) for
identical code.
Snapshot all three counters once at the top of Scheduler::call():
- NO_ATOMICS: single LockGuard, read three plain uint32_t fields.
- ATOMICS: three relaxed atomic loads (free, same order as the
per-helper fast paths).
- SINGLE: untouched — the existing direct container checks are
already cheap with no concurrent writers.
The three skip-work gates below then branch on the snapshot instead of
each calling its own _empty_() (and re-locking on NO_ATOMICS). When a
gate fires, the slow path is invoked directly so it still acquires the
lock fresh to read container state.
After process_defer_queue_slow_path_ runs, resnapshot to_add_count_ and
to_remove_: callbacks dispatched by the defer queue can call
set_timeout/set_interval/cancel_*, which mutate those counters. Missing
that refresh would cause the subsequent process_to_add / cleanup_ gates
to skip freshly-queued work for one tick. The defer queue itself is
drained inside the slow path so snap_defer is consumed by the single
call.
Measured on BK7238/BK7231N while debugging overhead alongside
libretiny-eu/libretiny#360.
Description
ESPHome is a system to control your ESP8266/ESP32 by simple yet powerful configuration files and control them remotely through Home Automation systems.
Readme
Multiple Licenses
546 MiB
Languages
C++
60.1%
Python
39.3%
C
0.3%
JavaScript
0.2%
