mirror of
https://github.com/esphome/esphome.git
synced 2026-09-11 15:27:33 +00:00
[core] Inline feed_wdt hot path with out-of-line slow path
Split Application::feed_wdt() into an ALWAYS_INLINE wrapper that checks the 3ms rate limit against last_wdt_feed_ and a feed_wdt_slow_() callee that performs the actual arch_feed_wdt() + status LED re-dispatch. Callers on the hot path (loop_task before/after each component) that already have a millis() timestamp in hand now pay only a load + sub + branch on the no-op path instead of a full call8 / entry / retw. Moves the rate-limit state from a function-local static to a class member (last_wdt_feed_) so the inline can access it.
This commit is contained in:
@@ -196,14 +196,15 @@ void Application::process_dump_config_() {
|
||||
this->dump_config_at_++;
|
||||
}
|
||||
|
||||
void HOT Application::feed_wdt(uint32_t time) {
|
||||
static uint32_t last_feed = 0;
|
||||
void HOT Application::feed_wdt_slow_(uint32_t time) {
|
||||
// Use provided time if available, otherwise get current time
|
||||
uint32_t now = time ? time : millis();
|
||||
// Compare in milliseconds (3ms threshold)
|
||||
if (now - last_feed > 3) {
|
||||
// Compare in milliseconds (3ms threshold). The inline wrapper already
|
||||
// performs this check when time != 0; repeat it here for the time == 0
|
||||
// entry and as a safety net.
|
||||
if (now - this->last_wdt_feed_ > 3) {
|
||||
arch_feed_wdt();
|
||||
last_feed = now;
|
||||
this->last_wdt_feed_ = now;
|
||||
#ifdef USE_STATUS_LED
|
||||
if (status_led::global_status_led != nullptr) {
|
||||
status_led::global_status_led->call();
|
||||
|
||||
@@ -385,7 +385,19 @@ class Application {
|
||||
|
||||
void schedule_dump_config() { this->dump_config_at_ = 0; }
|
||||
|
||||
void feed_wdt(uint32_t time = 0);
|
||||
/// Feed the task watchdog. Hot-path inline rate-limit check: callers that
|
||||
/// already have a timestamp in hand pay only a load + sub + branch on the
|
||||
/// common (no-op) path. The actual arch feed + status LED update live in
|
||||
/// feed_wdt_slow_ to keep this small enough to inline freely.
|
||||
///
|
||||
/// Pass time==0 to request millis() be read for you (low-frequency callers
|
||||
/// only — always takes the slow path).
|
||||
void ESPHOME_ALWAYS_INLINE feed_wdt(uint32_t time = 0) {
|
||||
if (time != 0 && static_cast<uint32_t>(time - this->last_wdt_feed_) <= 3) {
|
||||
return;
|
||||
}
|
||||
this->feed_wdt_slow_(time);
|
||||
}
|
||||
|
||||
void reboot();
|
||||
|
||||
@@ -615,7 +627,10 @@ class Application {
|
||||
/// Caller must ensure dump_config_at_ < components_.size().
|
||||
void __attribute__((noinline)) process_dump_config_();
|
||||
|
||||
void feed_wdt_arch_();
|
||||
/// Slow path for feed_wdt(): actually calls arch_feed_wdt(), updates
|
||||
/// last_wdt_feed_, and re-dispatches the status LED. Out of line so the
|
||||
/// inline wrapper stays tiny.
|
||||
void feed_wdt_slow_(uint32_t time);
|
||||
|
||||
/// Perform a delay while also monitoring socket file descriptors for readiness
|
||||
#ifdef USE_HOST
|
||||
@@ -669,6 +684,7 @@ class Application {
|
||||
// 4-byte members
|
||||
uint32_t last_loop_{0};
|
||||
uint32_t loop_component_start_time_{0};
|
||||
uint32_t last_wdt_feed_{0}; // millis() of most recent arch_feed_wdt(); rate-limits feed_wdt() hot path
|
||||
|
||||
#ifdef USE_HOST
|
||||
int max_fd_{-1}; // Highest file descriptor number for select()
|
||||
|
||||
Reference in New Issue
Block a user