Reduce web_server loop overhead on ESP32 by avoiding unnecessary semaphore operations (#9308)

This commit is contained in:
J. Nick Koston 2025-07-03 19:53:14 -05:00 committed by GitHub
parent 25457da97c
commit d00e20ccdf
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 8 additions and 1 deletions

View File

@ -299,7 +299,8 @@ void WebServer::setup() {
} }
void WebServer::loop() { void WebServer::loop() {
#ifdef USE_ESP32 #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<void()> fn; std::function<void()> fn;
if (!to_schedule_.empty()) { if (!to_schedule_.empty()) {
// scheduler execute things out of order which may lead to incorrect state // 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 // let's execute it directly from the loop
fn = std::move(to_schedule_.front()); fn = std::move(to_schedule_.front());
to_schedule_.pop_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_); xSemaphoreGive(this->to_schedule_lock_);
if (fn) { if (fn) {
@ -2061,6 +2065,7 @@ void WebServer::schedule_(std::function<void()> &&f) {
#ifdef USE_ESP32 #ifdef USE_ESP32
xSemaphoreTake(this->to_schedule_lock_, portMAX_DELAY); xSemaphoreTake(this->to_schedule_lock_, portMAX_DELAY);
to_schedule_.push_back(std::move(f)); to_schedule_.push_back(std::move(f));
this->to_schedule_has_items_.store(true, std::memory_order_relaxed);
xSemaphoreGive(this->to_schedule_lock_); xSemaphoreGive(this->to_schedule_lock_);
#else #else
this->defer(std::move(f)); this->defer(std::move(f));

View File

@ -18,6 +18,7 @@
#include <freertos/FreeRTOS.h> #include <freertos/FreeRTOS.h>
#include <freertos/semphr.h> #include <freertos/semphr.h>
#include <deque> #include <deque>
#include <atomic>
#endif #endif
#if USE_WEBSERVER_VERSION >= 2 #if USE_WEBSERVER_VERSION >= 2
@ -524,6 +525,7 @@ class WebServer : public Controller, public Component, public AsyncWebHandler {
#ifdef USE_ESP32 #ifdef USE_ESP32
std::deque<std::function<void()>> to_schedule_; std::deque<std::function<void()>> to_schedule_;
SemaphoreHandle_t to_schedule_lock_; SemaphoreHandle_t to_schedule_lock_;
std::atomic<bool> to_schedule_has_items_{false};
#endif #endif
}; };