Merge remote-tracking branch 'upstream-ssh/scheduler-pool-unbounded-freelist' into integration

This commit is contained in:
J. Nick Koston
2026-04-30 11:38:57 -05:00
2 changed files with 17 additions and 6 deletions
+13 -6
View File
@@ -913,6 +913,14 @@ void Scheduler::recycle_item_main_loop_(SchedulerItem *item) {
#endif
}
// Shrink a SchedulerItem* vector's capacity to its current size via the swap-with-copy
// idiom (std::vector::shrink_to_fit() is non-binding and our toolchain ignores it).
// Out-of-line + noinline so the callers in trim_freelist() share one body instead of
// inlining the construct-swap-destruct dance per call site (~440 B flash on ESP32).
void __attribute__((noinline)) Scheduler::shrink_scheduler_vector_(std::vector<SchedulerItem *> *v) {
std::vector<SchedulerItem *>(*v).swap(*v);
}
void Scheduler::trim_freelist() {
LockGuard guard{this->lock_};
SchedulerItem *item = this->scheduler_item_pool_head_;
@@ -929,13 +937,12 @@ void Scheduler::trim_freelist() {
this->scheduler_item_pool_head_ = nullptr;
this->scheduler_item_pool_size_ = 0;
// The vectors that back items_/to_add_/defer_queue_ also retain their boot-peak
// capacity (std::vector grows by doubling). Swap each with a same-content copy to
// reclaim the slack -- the new vector is sized exactly to its current contents.
std::vector<SchedulerItem *>(this->items_).swap(this->items_);
std::vector<SchedulerItem *>(this->to_add_).swap(this->to_add_);
// items_/to_add_/defer_queue_ retain their boot-peak vector capacity (vector grows
// by doubling and otherwise keeps the peak). Reclaim that slack as well.
shrink_scheduler_vector_(&this->items_);
shrink_scheduler_vector_(&this->to_add_);
#ifndef ESPHOME_THREAD_SINGLE
std::vector<SchedulerItem *>(this->defer_queue_).swap(this->defer_queue_);
shrink_scheduler_vector_(&this->defer_queue_);
#endif
#ifdef ESPHOME_DEBUG_SCHEDULER
+4
View File
@@ -365,6 +365,10 @@ class Scheduler {
SchedulerItem *get_item_from_pool_locked_();
private:
// Out-of-line helper that shrinks a SchedulerItem* vector's capacity to its current
// size. Centralised so trim_freelist() doesn't pay flash cost per call site.
static void shrink_scheduler_vector_(std::vector<SchedulerItem *> *v);
// Helper to cancel matching items - must be called with lock held.
// When find_first=true, stops after the first match (used by set_timer_common_ where
// the cancel-before-add invariant guarantees at most one match).