diff --git a/esphome/core/scheduler.cpp b/esphome/core/scheduler.cpp index 1a6e79eb31..03bab24e6c 100644 --- a/esphome/core/scheduler.cpp +++ b/esphome/core/scheduler.cpp @@ -476,7 +476,7 @@ void Scheduler::compact_defer_queue_locked_() { // (saves ~156 bytes flash). Erasing from the end is O(1) - no shifting needed. this->defer_queue_.erase(this->defer_queue_.begin() + remaining, this->defer_queue_.end()); } -void HOT Scheduler::process_defer_queue_slow_path_(uint32_t &now) { +void HOT Scheduler::process_defer_queue_(uint32_t &now) { // Process defer queue to guarantee FIFO execution order for deferred items. // Previously, defer() used the heap which gave undefined order for equal timestamps, // causing race conditions on multi-core systems (ESP32, BK7200). @@ -543,7 +543,7 @@ uint32_t HOT Scheduler::call(uint32_t now) { this->snapshot_counters_(snap_defer, snap_add, snap_remove); if (snap_defer > 0) { - this->process_defer_queue_slow_path_(now); + this->process_defer_queue_(now); // Defer callbacks may set_timeout/set_interval/cancel_*, mutating the // other two counters. Re-snapshot. this->snapshot_counters_(snap_defer, snap_add, snap_remove); diff --git a/esphome/core/scheduler.h b/esphome/core/scheduler.h index 9a18de5d9e..ab4c1c70cc 100644 --- a/esphome/core/scheduler.h +++ b/esphome/core/scheduler.h @@ -414,17 +414,9 @@ class Scheduler { #ifndef ESPHOME_THREAD_SINGLE // Process defer queue for FIFO execution of deferred items. // IMPORTANT: This method should only be called from the main thread (loop task). - // Inlined: the fast path (nothing deferred) is just an atomic load check. - inline void ESPHOME_ALWAYS_INLINE HOT process_defer_queue_(uint32_t &now) { - // Fast path: nothing to process, avoid lock entirely. - // Worst case is a one-loop-iteration delay before newly deferred items are processed. - if (this->defer_empty_()) - return; - this->process_defer_queue_slow_path_(now); - } - - // Slow path for process_defer_queue_() - defined in scheduler.cpp - void process_defer_queue_slow_path_(uint32_t &now); + // The fast path (nothing deferred) is handled by Scheduler::call()'s snapshot + // gate; this is only invoked when the snapshot saw defer_count_ > 0. + void process_defer_queue_(uint32_t &now); // Helper to cleanup defer_queue_ after processing. // Keeps the common clear() path inline, outlines the rare compaction to keep