[core] Optimize WarnIfComponentBlockingGuard::finish() hot path (#14040)

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
J. Nick Koston
2026-02-19 10:10:22 -06:00
committed by GitHub
parent 5304750215
commit f7459670d3
2 changed files with 22 additions and 23 deletions
+18 -20
View File
@@ -82,8 +82,8 @@ void store_component_error_message(const Component *component, const char *messa
// setup_priority, component state, and status LED constants are now // setup_priority, component state, and status LED constants are now
// constexpr in component.h // constexpr in component.h
const uint16_t WARN_IF_BLOCKING_OVER_MS = 50U; ///< Initial blocking time allowed without warning static constexpr uint16_t WARN_IF_BLOCKING_INCREMENT_MS =
const uint16_t WARN_IF_BLOCKING_INCREMENT_MS = 10U; ///< How long the blocking time must be larger to warn again 10U; ///< How long the blocking time must be larger to warn again
float Component::get_loop_priority() const { return 0.0f; } float Component::get_loop_priority() const { return 0.0f; }
@@ -529,37 +529,35 @@ void PollingComponent::stop_poller() {
uint32_t PollingComponent::get_update_interval() const { return this->update_interval_; } 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; } void PollingComponent::set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
WarnIfComponentBlockingGuard::WarnIfComponentBlockingGuard(Component *component, uint32_t start_time) static void __attribute__((noinline, cold)) warn_blocking(Component *component, uint32_t blocking_time) {
: started_(start_time), component_(component) {} bool should_warn;
if (component != nullptr) {
should_warn = component->should_warn_of_blocking(blocking_time);
} else {
should_warn = true; // Already checked > WARN_IF_BLOCKING_OVER_MS in caller
}
if (should_warn) {
ESP_LOGW(TAG, "%s took a long time for an operation (%" PRIu32 " ms), max is 30 ms",
component == nullptr ? LOG_STR_LITERAL("<null>") : LOG_STR_ARG(component->get_component_log_str()),
blocking_time);
}
}
uint32_t WarnIfComponentBlockingGuard::finish() { uint32_t WarnIfComponentBlockingGuard::finish() {
uint32_t curr_time = millis(); uint32_t curr_time = millis();
uint32_t blocking_time = curr_time - this->started_; uint32_t blocking_time = curr_time - this->started_;
#ifdef USE_RUNTIME_STATS #ifdef USE_RUNTIME_STATS
// Record component runtime stats // Record component runtime stats
if (global_runtime_stats != nullptr) { if (global_runtime_stats != nullptr) {
global_runtime_stats->record_component_time(this->component_, blocking_time, curr_time); global_runtime_stats->record_component_time(this->component_, blocking_time, curr_time);
} }
#endif #endif
bool should_warn; if (blocking_time > WARN_IF_BLOCKING_OVER_MS) {
if (this->component_ != nullptr) { warn_blocking(this->component_, blocking_time);
should_warn = this->component_->should_warn_of_blocking(blocking_time);
} else {
should_warn = blocking_time > WARN_IF_BLOCKING_OVER_MS;
} }
if (should_warn) {
ESP_LOGW(TAG, "%s took a long time for an operation (%" PRIu32 " ms)",
component_ == nullptr ? LOG_STR_LITERAL("<null>") : LOG_STR_ARG(component_->get_component_log_str()),
blocking_time);
ESP_LOGW(TAG, "Components should block for at most 30 ms");
}
return curr_time; return curr_time;
} }
WarnIfComponentBlockingGuard::~WarnIfComponentBlockingGuard() {}
#ifdef USE_SETUP_PRIORITY_OVERRIDE #ifdef USE_SETUP_PRIORITY_OVERRIDE
void clear_setup_priority_overrides() { void clear_setup_priority_overrides() {
// Free the setup priority map completely // Free the setup priority map completely
+4 -3
View File
@@ -79,7 +79,7 @@ inline constexpr uint8_t STATUS_LED_ERROR = 0x10;
// Remove before 2026.8.0 // Remove before 2026.8.0
enum class RetryResult { DONE, RETRY }; enum class RetryResult { DONE, RETRY };
extern const uint16_t WARN_IF_BLOCKING_OVER_MS; inline constexpr uint16_t WARN_IF_BLOCKING_OVER_MS = 50U;
class Component { class Component {
public: public:
@@ -550,12 +550,13 @@ class PollingComponent : public Component {
class WarnIfComponentBlockingGuard { class WarnIfComponentBlockingGuard {
public: public:
WarnIfComponentBlockingGuard(Component *component, uint32_t start_time); WarnIfComponentBlockingGuard(Component *component, uint32_t start_time)
: started_(start_time), component_(component) {}
// Finish the timing operation and return the current time // Finish the timing operation and return the current time
uint32_t finish(); uint32_t finish();
~WarnIfComponentBlockingGuard(); ~WarnIfComponentBlockingGuard() = default;
protected: protected:
uint32_t started_; uint32_t started_;