From d00e20ccdf0b2c9e1e82424f60f3814908ac7fbf Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Thu, 3 Jul 2025 19:53:14 -0500 Subject: [PATCH] Reduce web_server loop overhead on ESP32 by avoiding unnecessary semaphore operations (#9308) --- esphome/components/web_server/web_server.cpp | 7 ++++++- esphome/components/web_server/web_server.h | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/esphome/components/web_server/web_server.cpp b/esphome/components/web_server/web_server.cpp index 1242db57ff..f576507c0f 100644 --- a/esphome/components/web_server/web_server.cpp +++ b/esphome/components/web_server/web_server.cpp @@ -299,7 +299,8 @@ void WebServer::setup() { } void WebServer::loop() { #ifdef USE_ESP32 - if (xSemaphoreTake(this->to_schedule_lock_, 0L)) { + // Check atomic flag first to avoid taking semaphore when queue is empty + if (this->to_schedule_has_items_.load(std::memory_order_relaxed) && xSemaphoreTake(this->to_schedule_lock_, 0L)) { std::function fn; if (!to_schedule_.empty()) { // scheduler execute things out of order which may lead to incorrect state @@ -307,6 +308,9 @@ void WebServer::loop() { // let's execute it directly from the loop fn = std::move(to_schedule_.front()); to_schedule_.pop_front(); + if (to_schedule_.empty()) { + this->to_schedule_has_items_.store(false, std::memory_order_relaxed); + } } xSemaphoreGive(this->to_schedule_lock_); if (fn) { @@ -2061,6 +2065,7 @@ void WebServer::schedule_(std::function &&f) { #ifdef USE_ESP32 xSemaphoreTake(this->to_schedule_lock_, portMAX_DELAY); to_schedule_.push_back(std::move(f)); + this->to_schedule_has_items_.store(true, std::memory_order_relaxed); xSemaphoreGive(this->to_schedule_lock_); #else this->defer(std::move(f)); diff --git a/esphome/components/web_server/web_server.h b/esphome/components/web_server/web_server.h index 5f175b6bdd..c654d83bbd 100644 --- a/esphome/components/web_server/web_server.h +++ b/esphome/components/web_server/web_server.h @@ -18,6 +18,7 @@ #include #include #include +#include #endif #if USE_WEBSERVER_VERSION >= 2 @@ -524,6 +525,7 @@ class WebServer : public Controller, public Component, public AsyncWebHandler { #ifdef USE_ESP32 std::deque> to_schedule_; SemaphoreHandle_t to_schedule_lock_; + std::atomic to_schedule_has_items_{false}; #endif };