This commit is contained in:
Tomasz Duda
2026-02-08 14:21:33 +01:00
parent 82eb4538af
commit 1e7eda1a67
3 changed files with 14 additions and 7 deletions
@@ -60,7 +60,7 @@ void TaskLogBuffer::release_message_main_loop() {
last_processed_counter_ = message_counter_.load(std::memory_order_relaxed);
}
bool TaskLogBuffer::send_message_thread_safe(uint8_t level, const char *tag, uint16_t line, TaskHandle_t task_handle,
bool TaskLogBuffer::send_message_thread_safe(uint8_t level, const char *tag, uint16_t line, void *task_handle,
const char *format, va_list args) {
// First, calculate the exact length needed using a null buffer (no actual writing)
va_list args_copy;
@@ -96,7 +96,7 @@ bool TaskLogBuffer::send_message_thread_safe(uint8_t level, const char *tag, uin
// Store the thread name now instead of waiting until main loop processing
// This avoids crashes if the task completes or is deleted between when this message
// is enqueued and when it's processed by the main loop
const char *thread_name = pcTaskGetName(task_handle);
const char *thread_name = pcTaskGetName(static_cast<TaskHandle_t>(task_handle));
if (thread_name != nullptr) {
strncpy(msg->thread_name, thread_name, sizeof(msg->thread_name) - 1);
msg->thread_name[sizeof(msg->thread_name) - 1] = '\0'; // Ensure null termination
@@ -58,8 +58,8 @@ class TaskLogBuffer {
void release_message_main_loop();
// Thread-safe - send a message to the ring buffer from any thread
bool send_message_thread_safe(uint8_t level, const char *tag, uint16_t line, TaskHandle_t task_handle,
const char *format, va_list args);
bool send_message_thread_safe(uint8_t level, const char *tag, uint16_t line, void *task_handle, const char *format,
va_list args);
// Check if there are messages ready to be processed using an atomic counter for performance
inline bool HOT has_messages() const {
@@ -6,13 +6,19 @@ namespace esphome::logger {
__thread bool non_main_task_recursion_guard_;
static inline uint32_t get_wlen(const mpsc_pbuf_generic *item) {
auto *msg = reinterpret_cast<const TaskLogBufferZephyr::LogMessage *>(item);
// Calculate total size in 32-bit words needed (header + text length + null terminator + 3(4 bytes alignment)
return (sizeof(TaskLogBufferZephyr::LogMessage) + msg->text_length + 1 + 3) / sizeof(uint32_t);
}
TaskLogBufferZephyr::TaskLogBufferZephyr(size_t total_buffer_size) {
// alignment to 4 bytes
total_buffer_size = (total_buffer_size + 3) / sizeof(uint32_t);
this->mpsc_config_.buf = new uint32_t[total_buffer_size];
this->mpsc_config_.size = total_buffer_size;
this->mpsc_config_.flags = MPSC_PBUF_MODE_OVERWRITE;
// .get_wlen = log_msg_generic_get_wlen,
this->mpsc_config_.get_wlen = get_wlen,
mpsc_pbuf_init(&this->log_buffer_, &this->mpsc_config_);
}
@@ -36,7 +42,7 @@ bool TaskLogBufferZephyr::send_message_thread_safe(uint8_t level, const char *ta
size_t text_length = (static_cast<size_t>(ret) > MAX_TEXT_SIZE) ? MAX_TEXT_SIZE : ret;
// Calculate total size in 32-bit words needed (header + text length + null terminator + 3(4 bytes alignment)
size_t total_size = (sizeof(LogMessage) + text_length + 1 + 3) / sizeof(uint32_t);
auto msg = reinterpret_cast<LogMessage *>(mpsc_pbuf_alloc(&this->log_buffer_, total_size, K_NO_WAIT));
auto *msg = reinterpret_cast<LogMessage *>(mpsc_pbuf_alloc(&this->log_buffer_, total_size, K_NO_WAIT));
if (nullptr == msg) {
return false;
}
@@ -47,7 +53,7 @@ bool TaskLogBufferZephyr::send_message_thread_safe(uint8_t level, const char *ta
if (thread_name) {
strncpy(msg->thread_name, thread_name, sizeof(msg->thread_name) - 1);
} else {
std::snprintf(msg->thread_name, MAX_POINTER_REPRESENTATION, "%p", task_handle);
std::snprintf(msg->thread_name, sizeof(msg->thread_name), "%p", task_handle);
}
// Format the message text directly into the acquired memory
@@ -64,6 +70,7 @@ bool TaskLogBufferZephyr::send_message_thread_safe(uint8_t level, const char *ta
text_area[i] = '\n';
}
text_area[text_length] = 0;
// do not return false to free the buffer from main thread
}
msg->text_length = text_length;