mirror of
https://github.com/esphome/esphome.git
synced 2025-11-08 02:51:49 +00:00
[scheduler] Extract helper functions to improve code readability (#11730)
This commit is contained in:
@@ -117,12 +117,8 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type
|
|||||||
item->set_name(name_cstr, !is_static_string);
|
item->set_name(name_cstr, !is_static_string);
|
||||||
item->type = type;
|
item->type = type;
|
||||||
item->callback = std::move(func);
|
item->callback = std::move(func);
|
||||||
// Initialize remove to false (though it should already be from constructor)
|
// Reset remove flag - recycled items may have been cancelled (remove=true) in previous use
|
||||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
this->set_item_removed_(item.get(), false);
|
||||||
item->remove.store(false, std::memory_order_relaxed);
|
|
||||||
#else
|
|
||||||
item->remove = false;
|
|
||||||
#endif
|
|
||||||
item->is_retry = is_retry;
|
item->is_retry = is_retry;
|
||||||
|
|
||||||
#ifndef ESPHOME_THREAD_SINGLE
|
#ifndef ESPHOME_THREAD_SINGLE
|
||||||
@@ -153,21 +149,7 @@ void HOT Scheduler::set_timer_common_(Component *component, SchedulerItem::Type
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ESPHOME_DEBUG_SCHEDULER
|
#ifdef ESPHOME_DEBUG_SCHEDULER
|
||||||
// Validate static strings in debug mode
|
this->debug_log_timer_(item.get(), is_static_string, name_cstr, type, delay, now);
|
||||||
if (is_static_string && name_cstr != nullptr) {
|
|
||||||
validate_static_string(name_cstr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Debug logging
|
|
||||||
const char *type_str = (type == SchedulerItem::TIMEOUT) ? "timeout" : "interval";
|
|
||||||
if (type == SchedulerItem::TIMEOUT) {
|
|
||||||
ESP_LOGD(TAG, "set_%s(name='%s/%s', %s=%" PRIu32 ")", type_str, LOG_STR_ARG(item->get_source()),
|
|
||||||
name_cstr ? name_cstr : "(null)", type_str, delay);
|
|
||||||
} else {
|
|
||||||
ESP_LOGD(TAG, "set_%s(name='%s/%s', %s=%" PRIu32 ", offset=%" PRIu32 ")", type_str, LOG_STR_ARG(item->get_source()),
|
|
||||||
name_cstr ? name_cstr : "(null)", type_str, delay,
|
|
||||||
static_cast<uint32_t>(item->get_next_execution() - now));
|
|
||||||
}
|
|
||||||
#endif /* ESPHOME_DEBUG_SCHEDULER */
|
#endif /* ESPHOME_DEBUG_SCHEDULER */
|
||||||
|
|
||||||
// For retries, check if there's a cancelled timeout first
|
// For retries, check if there's a cancelled timeout first
|
||||||
@@ -787,4 +769,25 @@ void Scheduler::recycle_item_(std::unique_ptr<SchedulerItem> item) {
|
|||||||
// else: unique_ptr will delete the item when it goes out of scope
|
// else: unique_ptr will delete the item when it goes out of scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ESPHOME_DEBUG_SCHEDULER
|
||||||
|
void Scheduler::debug_log_timer_(const SchedulerItem *item, bool is_static_string, const char *name_cstr,
|
||||||
|
SchedulerItem::Type type, uint32_t delay, uint64_t now) {
|
||||||
|
// Validate static strings in debug mode
|
||||||
|
if (is_static_string && name_cstr != nullptr) {
|
||||||
|
validate_static_string(name_cstr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Debug logging
|
||||||
|
const char *type_str = (type == SchedulerItem::TIMEOUT) ? "timeout" : "interval";
|
||||||
|
if (type == SchedulerItem::TIMEOUT) {
|
||||||
|
ESP_LOGD(TAG, "set_%s(name='%s/%s', %s=%" PRIu32 ")", type_str, LOG_STR_ARG(item->get_source()),
|
||||||
|
name_cstr ? name_cstr : "(null)", type_str, delay);
|
||||||
|
} else {
|
||||||
|
ESP_LOGD(TAG, "set_%s(name='%s/%s', %s=%" PRIu32 ", offset=%" PRIu32 ")", type_str, LOG_STR_ARG(item->get_source()),
|
||||||
|
name_cstr ? name_cstr : "(null)", type_str, delay,
|
||||||
|
static_cast<uint32_t>(item->get_next_execution() - now));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* ESPHOME_DEBUG_SCHEDULER */
|
||||||
|
|
||||||
} // namespace esphome
|
} // namespace esphome
|
||||||
|
|||||||
@@ -266,6 +266,12 @@ class Scheduler {
|
|||||||
// Helper to perform full cleanup when too many items are cancelled
|
// Helper to perform full cleanup when too many items are cancelled
|
||||||
void full_cleanup_removed_items_();
|
void full_cleanup_removed_items_();
|
||||||
|
|
||||||
|
#ifdef ESPHOME_DEBUG_SCHEDULER
|
||||||
|
// Helper for debug logging in set_timer_common_ - extracted to reduce code size
|
||||||
|
void debug_log_timer_(const SchedulerItem *item, bool is_static_string, const char *name_cstr,
|
||||||
|
SchedulerItem::Type type, uint32_t delay, uint64_t now);
|
||||||
|
#endif /* ESPHOME_DEBUG_SCHEDULER */
|
||||||
|
|
||||||
#ifndef ESPHOME_THREAD_SINGLE
|
#ifndef ESPHOME_THREAD_SINGLE
|
||||||
// Helper to process defer queue - inline for performance in hot path
|
// Helper to process defer queue - inline for performance in hot path
|
||||||
inline void process_defer_queue_(uint32_t &now) {
|
inline void process_defer_queue_(uint32_t &now) {
|
||||||
@@ -367,6 +373,24 @@ class Scheduler {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Helper to set item removal flag (platform-specific)
|
||||||
|
// For ESPHOME_THREAD_MULTI_NO_ATOMICS platforms, the caller must hold the scheduler lock before calling this
|
||||||
|
// function. Uses memory_order_release when setting to true (for cancellation synchronization),
|
||||||
|
// and memory_order_relaxed when setting to false (for initialization).
|
||||||
|
void set_item_removed_(SchedulerItem *item, bool removed) {
|
||||||
|
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
||||||
|
// Multi-threaded with atomics: use atomic store with appropriate ordering
|
||||||
|
// Release ordering when setting to true ensures cancellation is visible to other threads
|
||||||
|
// Relaxed ordering when setting to false is sufficient for initialization
|
||||||
|
item->remove.store(removed, removed ? std::memory_order_release : std::memory_order_relaxed);
|
||||||
|
#else
|
||||||
|
// Single-threaded (ESPHOME_THREAD_SINGLE) or
|
||||||
|
// multi-threaded without atomics (ESPHOME_THREAD_MULTI_NO_ATOMICS): direct write
|
||||||
|
// For ESPHOME_THREAD_MULTI_NO_ATOMICS, caller MUST hold lock!
|
||||||
|
item->remove = removed;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// Helper to mark matching items in a container as removed
|
// Helper to mark matching items in a container as removed
|
||||||
// Returns the number of items marked for removal
|
// Returns the number of items marked for removal
|
||||||
// IMPORTANT: Caller must hold the scheduler lock before calling this function.
|
// IMPORTANT: Caller must hold the scheduler lock before calling this function.
|
||||||
@@ -383,15 +407,7 @@ class Scheduler {
|
|||||||
continue;
|
continue;
|
||||||
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
if (this->matches_item_(item, component, name_cstr, type, match_retry)) {
|
||||||
// Mark item for removal (platform-specific)
|
// Mark item for removal (platform-specific)
|
||||||
#ifdef ESPHOME_THREAD_MULTI_ATOMICS
|
this->set_item_removed_(item.get(), true);
|
||||||
// Multi-threaded with atomics: use atomic store
|
|
||||||
item->remove.store(true, std::memory_order_release);
|
|
||||||
#else
|
|
||||||
// Single-threaded (ESPHOME_THREAD_SINGLE) or
|
|
||||||
// multi-threaded without atomics (ESPHOME_THREAD_MULTI_NO_ATOMICS): direct write
|
|
||||||
// For ESPHOME_THREAD_MULTI_NO_ATOMICS, caller MUST hold lock!
|
|
||||||
item->remove = true;
|
|
||||||
#endif
|
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user