Merge branch 'logger_disable_loop' into integration

This commit is contained in:
J. Nick Koston
2025-06-20 22:54:40 +02:00
2 changed files with 35 additions and 2 deletions

View File

@@ -48,6 +48,11 @@ void HOT Logger::log_vprintf_(int level, const char *tag, int line, const char *
// For non-main tasks, queue the message for callbacks - but only if we have any callbacks registered
message_sent = this->log_buffer_->send_message_thread_safe(static_cast<uint8_t>(level), tag,
static_cast<uint16_t>(line), current_task, format, args);
if (message_sent) {
// Enable logger loop to process the buffered message
// This is safe to call from any context including ISRs
this->enable_loop_soon_any_context();
}
#endif // USE_ESPHOME_TASK_LOG_BUFFER
// Emergency console logging for non-main tasks when ring buffer is full or disabled
@@ -139,10 +144,14 @@ Logger::Logger(uint32_t baud_rate, size_t tx_buffer_size) : baud_rate_(baud_rate
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
void Logger::init_log_buffer(size_t total_buffer_size) {
this->log_buffer_ = esphome::make_unique<logger::TaskLogBuffer>(total_buffer_size);
// Start with loop disabled when using task buffer (unless using USB CDC)
// The loop will be enabled automatically when messages arrive
this->disable_loop_when_buffer_empty_();
}
#endif
#if defined(USE_LOGGER_USB_CDC) || defined(USE_ESP32)
#if defined(USE_LOGGER_USB_CDC) || defined(USE_ESPHOME_TASK_LOG_BUFFER)
void Logger::loop() {
#if defined(USE_LOGGER_USB_CDC) && defined(USE_ARDUINO)
if (this->uart_ == UART_SELECTION_USB_CDC) {
@@ -189,6 +198,10 @@ void Logger::loop() {
this->write_msg_(this->tx_buffer_);
}
}
} else {
// No messages to process, disable loop if appropriate
// This reduces overhead when there's no async logging activity
this->disable_loop_when_buffer_empty_();
}
#endif
}

View File

@@ -107,7 +107,7 @@ class Logger : public Component {
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
void init_log_buffer(size_t total_buffer_size);
#endif
#if defined(USE_LOGGER_USB_CDC) || defined(USE_ESP32)
#if defined(USE_LOGGER_USB_CDC) || defined(USE_ESPHOME_TASK_LOG_BUFFER)
void loop() override;
#endif
/// Manually set the baud rate for serial, set to 0 to disable.
@@ -347,6 +347,26 @@ class Logger : public Component {
static const int RESET_COLOR_LEN = strlen(ESPHOME_LOG_RESET_COLOR);
this->write_body_to_buffer_(ESPHOME_LOG_RESET_COLOR, RESET_COLOR_LEN, buffer, buffer_at, buffer_size);
}
#ifdef USE_ESPHOME_TASK_LOG_BUFFER
// Disable loop when task buffer is empty (with USB CDC check)
inline void disable_loop_when_buffer_empty_() {
// Thread safety note: This is safe even if another task calls enable_loop_soon_any_context()
// concurrently. If that happens between our check and disable_loop(), the enable request
// will be processed on the next main loop iteration since:
// - disable_loop() takes effect immediately
// - enable_loop_soon_any_context() sets a pending flag that's checked at loop start
#if defined(USE_LOGGER_USB_CDC) && defined(USE_ARDUINO)
// Only disable if not using USB CDC (which needs loop for connection detection)
if (this->uart_ != UART_SELECTION_USB_CDC) {
this->disable_loop();
}
#else
// No USB CDC support, always safe to disable
this->disable_loop();
#endif
}
#endif
};
extern Logger *global_logger; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables)