[core] Inline WarnIfComponentBlockingGuard::finish() into header (#14798)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
J. Nick Koston
2026-03-16 07:35:19 -10:00
committed by GitHub
parent 7131eafc09
commit 808c7b67b3
2 changed files with 23 additions and 13 deletions

View File

@@ -510,7 +510,8 @@ void PollingComponent::stop_poller() {
uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; }
void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
static void __attribute__((noinline, cold)) warn_blocking(Component *component, uint32_t blocking_time) {
void __attribute__((noinline, cold))
WarnIfComponentBlockingGuard::warn_blocking(Component *component, uint32_t blocking_time) {
bool should_warn;
if (component != nullptr) {
should_warn = component->should_warn_of_blocking(blocking_time);
@@ -524,10 +525,8 @@ static void __attribute__((noinline, cold)) warn_blocking(Component *component,
}
}
uint32_t WarnIfComponentBlockingGuard::finish() {
uint32_t curr_time = millis();
uint32_t blocking_time = curr_time - this->started_;
#ifdef USE_RUNTIME_STATS
void WarnIfComponentBlockingGuard::record_runtime_stats_() {
// Use micros() for accurate sub-millisecond timing. millis() has insufficient
// resolution — most components complete in microseconds but millis() only has
// 1ms granularity, so results were essentially random noise.
@@ -535,12 +534,8 @@ uint32_t WarnIfComponentBlockingGuard::finish() {
uint32_t duration_us = micros() - this->started_us_;
global_runtime_stats->record_component_time(this->component_, duration_us);
}
#endif
if (blocking_time > WARN_IF_BLOCKING_OVER_MS) {
warn_blocking(this->component_, blocking_time);
}
return curr_time;
}
#endif
#ifdef USE_SETUP_PRIORITY_OVERRIDE
void clear_setup_priority_overrides() {

View File

@@ -6,6 +6,7 @@
#include <string>
#include "esphome/core/defines.h"
#include "esphome/core/hal.h"
#include "esphome/core/helpers.h"
#include "esphome/core/log.h"
#include "esphome/core/optional.h"
@@ -575,9 +576,7 @@ class PollingComponent : public Component {
uint32_t update_interval_;
};
#ifdef USE_RUNTIME_STATS
uint32_t micros(); // Forward declare for inline constructor
#endif
// millis() and micros() are available via hal.h
class WarnIfComponentBlockingGuard {
public:
@@ -592,7 +591,18 @@ class WarnIfComponentBlockingGuard {
}
// Finish the timing operation and return the current time
uint32_t finish();
// Inlined: the fast path is just millis() + subtract + compare
inline uint32_t HOT finish() {
uint32_t curr_time = millis();
uint32_t blocking_time = curr_time - this->started_;
#ifdef USE_RUNTIME_STATS
this->record_runtime_stats_();
#endif
if (blocking_time > WARN_IF_BLOCKING_OVER_MS) [[unlikely]] {
warn_blocking(this->component_, blocking_time);
}
return curr_time;
}
~WarnIfComponentBlockingGuard() = default;
@@ -601,7 +611,12 @@ class WarnIfComponentBlockingGuard {
Component *component_;
#ifdef USE_RUNTIME_STATS
uint32_t started_us_;
void record_runtime_stats_();
#endif
private:
// Cold path for blocking warning - defined in component.cpp
static void __attribute__((noinline, cold)) warn_blocking(Component *component, uint32_t blocking_time);
};
// Function to clear setup priority overrides after all components are set up