5#ifdef USE_ESPHOME_TASK_LOG_BUFFER
13int TaskLogBuffer::acquire_write_slot_() {
15 size_t current_reserve = this->reserve_index_.load(std::memory_order_relaxed);
19 size_t next_reserve = (current_reserve + 1) % ESPHOME_TASK_LOG_BUFFER_SIZE;
23 size_t current_read = this->read_index_.load(std::memory_order_acquire);
24 if (next_reserve == current_read) {
29 if (this->reserve_index_.compare_exchange_weak(current_reserve, next_reserve, std::memory_order_acq_rel,
30 std::memory_order_relaxed)) {
31 return static_cast<int>(current_reserve);
37void TaskLogBuffer::commit_write_slot_(
int slot_index) {
39 this->slots_[slot_index].
ready.store(
true, std::memory_order_release);
43 size_t expected = slot_index;
44 size_t next = (slot_index + 1) % ESPHOME_TASK_LOG_BUFFER_SIZE;
49 if (!this->write_index_.compare_exchange_weak(expected, next, std::memory_order_release,
50 std::memory_order_relaxed)) {
57 next = (next + 1) % ESPHOME_TASK_LOG_BUFFER_SIZE;
58 if (!this->slots_[expected].ready.load(std::memory_order_acquire)) {
67 int slot_index = this->acquire_write_slot_();
72 LogMessage &msg = this->slots_[slot_index];
80 if (thread_name !=
nullptr) {
81 strncpy(msg.thread_name, thread_name,
sizeof(msg.thread_name) - 1);
82 msg.thread_name[
sizeof(msg.thread_name) - 1] =
'\0';
84 msg.thread_name[0] =
'\0';
88 int ret = vsnprintf(msg.text,
sizeof(msg.text),
format,
args);
94 msg.text_length =
static_cast<uint16_t
>(std::min(
static_cast<size_t>(ret),
sizeof(msg.text) - 1));
98 while (msg.text_length > 0 && msg.text[msg.text_length - 1] ==
'\n') {
101 msg.text[msg.text_length] =
'\0';
104 this->commit_write_slot_(slot_index);
110 size_t current_read = this->read_index_.load(std::memory_order_relaxed);
111 size_t current_write = this->write_index_.load(std::memory_order_acquire);
114 if (current_read == current_write) {
119 LogMessage &msg = this->slots_[current_read];
120 if (!msg.ready.load(std::memory_order_acquire)) {
130 size_t current_read = this->read_index_.load(std::memory_order_relaxed);
133 this->slots_[current_read].
ready.store(
false, std::memory_order_release);
136 size_t next_read = (current_read + 1) % ESPHOME_TASK_LOG_BUFFER_SIZE;
137 this->read_index_.store(next_read, std::memory_order_release);
void release_message_main_loop()
bool borrow_message_main_loop(LogMessage *&message, uint16_t &text_length)
bool send_message_thread_safe(uint8_t level, const char *tag, uint16_t line, const char *thread_name, const char *format, va_list args)
const char int const __FlashStringHelper * format
const char int const __FlashStringHelper va_list args
std::atomic< bool > ready