5#ifdef USE_ESPHOME_TASK_LOG_BUFFER
15 this->slots_ = std::make_unique<LogMessage[]>(slot_count);
18TaskLogBuffer::~TaskLogBuffer() {
22int TaskLogBuffer::acquire_write_slot_() {
24 size_t current_reserve = this->reserve_index_.load(std::memory_order_relaxed);
28 size_t next_reserve = (current_reserve + 1) % this->slot_count_;
32 size_t current_read = this->read_index_.load(std::memory_order_acquire);
33 if (next_reserve == current_read) {
38 if (this->reserve_index_.compare_exchange_weak(current_reserve, next_reserve, std::memory_order_acq_rel,
39 std::memory_order_relaxed)) {
40 return static_cast<int>(current_reserve);
46void TaskLogBuffer::commit_write_slot_(
int slot_index) {
48 this->slots_[slot_index].ready.store(
true, std::memory_order_release);
52 size_t expected = slot_index;
53 size_t next = (slot_index + 1) % this->slot_count_;
58 if (!this->write_index_.compare_exchange_weak(expected, next, std::memory_order_release,
59 std::memory_order_relaxed)) {
66 next = (next + 1) % this->slot_count_;
67 if (!this->slots_[expected].ready.load(std::memory_order_acquire)) {
73bool TaskLogBuffer::send_message_thread_safe(uint8_t level,
const char *tag, uint16_t line,
const char *thread_name,
74 const char *format, va_list args) {
76 int slot_index = this->acquire_write_slot_();
81 LogMessage &msg = this->slots_[slot_index];
89 if (thread_name !=
nullptr) {
90 strncpy(msg.thread_name, thread_name,
sizeof(msg.thread_name) - 1);
91 msg.thread_name[
sizeof(msg.thread_name) - 1] =
'\0';
93 msg.thread_name[0] =
'\0';
97 int ret = vsnprintf(msg.text,
sizeof(msg.text), format, args);
103 msg.text_length =
static_cast<uint16_t
>(std::min(
static_cast<size_t>(ret),
sizeof(msg.text) - 1));
107 while (msg.text_length > 0 && msg.text[msg.text_length - 1] ==
'\n') {
110 msg.text[msg.text_length] =
'\0';
113 this->commit_write_slot_(slot_index);
118bool TaskLogBuffer::borrow_message_main_loop(LogMessage *&
message, uint16_t &text_length) {
119 size_t current_read = this->read_index_.load(std::memory_order_relaxed);
120 size_t current_write = this->write_index_.load(std::memory_order_acquire);
123 if (current_read == current_write) {
128 LogMessage &msg = this->slots_[current_read];
129 if (!msg.ready.load(std::memory_order_acquire)) {
134 text_length = msg.text_length;
138void TaskLogBuffer::release_message_main_loop() {
139 size_t current_read = this->read_index_.load(std::memory_order_relaxed);
142 this->slots_[current_read].ready.store(
false, std::memory_order_release);
145 size_t next_read = (current_read + 1) % this->slot_count_;
146 this->read_index_.store(next_read, std::memory_order_release);
TaskLogBuffer(size_t total_buffer_size)