Eliminate redundant xTaskGetCurrentTaskHandle() and pcTaskGetName()
calls on the hot path by resolving the thread name once in log_vprintf_
and passing it through as const char* to all downstream functions.
- Main task fast path passes nullptr (no task handle lookup needed)
- Non-main thread path resolves name once, passes to both ring buffer
and emergency console fallback
- Unify log_vprintf_non_main_thread_ to single signature across platforms
- Change send_message_thread_safe() on all platforms from TaskHandle_t
to const char* thread_name
- Add TaskHandle_t overload for get_thread_name_ as primary on
ESP32/LibreTiny, with no-arg convenience wrapper
- Use std::span<char> for Host/Zephyr get_thread_name_ buffer parameter
- Document Zephyr single-task path thread safety limitation
When a subprocess exited, _proc_on_exit sent the exit event but never
closed the server-side WebSocket. This left zombie connections open
until the client eventually disconnected.
Read all available bytes in batches via read_array() instead of
byte-at-a-time read() calls. Each read() internally chains through
read_byte -> read_array(1) -> check_read_timeout_ -> available(),
resulting in 3 UART calls per byte. Batching reduces this
significantly.
Read all available bytes in batches via read_array() instead of
byte-at-a-time read() calls. Each read() internally chains through
read_byte -> read_array(1) -> check_read_timeout_ -> available(),
resulting in 3 UART calls per byte. At 256000 baud with ~235 bytes
per loop iteration, this was ~706 UART operations per loop call.
Batching reduces this to ~12.
Measured 33% reduction in loop time (2348ms -> 1577ms per 60s).
Add _to() variants that write into a stack buffer and return StringRef,
avoiding heap allocation on every publish. Update publish_state() in
climate (11 allocations eliminated), fan (3), cover (2), and valve (1)
to use the new stack-based getters.
The allocating getters are retained for setup-time paths (subscribe,
send_discovery, dump_config) where the allocation is one-time.
The on_log callback was constructing a temporary MQTTMessage struct which
copied the log_message_ topic string and created a new std::string from
the message buffer on every log line. This is called frequently at runtime
and contributes to heap fragmentation.
Use the const char* publish overload directly to avoid both allocations.