mirror of
https://github.com/esphome/esphome.git
synced 2026-09-04 03:56:04 +00:00
[core] Factor trim_freelist() vector shrink into out-of-line helper
The three swap-with-copy lines in trim_freelist() inlined the construct-swap-destruct dance per call site, costing ~440 B flash on ESP32. Move the swap-shrink into a noinline private static helper so all three callers share one body. Net flash cost of vector shrinking drops to ~296 B (from ~444 B) while preserving the same RAM-reclaim behaviour. shrink_to_fit() is a non-binding hint that the toolchain ignores, so the swap-with-copy idiom is still required.
This commit is contained in:
@@ -899,6 +899,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_;
|
||||
@@ -915,13 +923,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
|
||||
|
||||
@@ -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).
|
||||
|
||||
Reference in New Issue
Block a user