mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 06:33:51 +00:00 
			
		
		
		
	Reduce logger CPU usage by disabling loop when buffer is empty
This commit is contained in:
		| @@ -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 | ||||
| } | ||||
|   | ||||
| @@ -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) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user