[core] Inline Mutex on FreeRTOS platforms (ESP32, LibreTiny)

Move FreeRTOS Mutex methods inline into helpers.h, eliminating
duplicate out-of-line definitions in esp32/helpers.cpp and
libretiny/helpers.cpp.

Hot path impact (disassembled from ELF):

| Platform           | Before   | After    | Saved   |
|--------------------|----------|----------|---------|
| ESP32 (Xtensa)     | 1304 B   | 1270 B   | -34 B   |
| BK72xx (ARM M4)    | 1400 B   | 1396 B   | -4 B    |
| RTL87xx (ARM M33)  | 1248 B   | 1246 B   | -2 B    |
| ESP32-C3 (RISC-V)  | 1498 B   | 1494 B   | -4 B    |

GCC generates ISRA clones that hoist the handle_ load into callers
and use tail calls to xQueueSemaphoreTake/xQueueGenericSend.
This commit is contained in:
J. Nick Koston
2026-03-13 22:23:30 -10:00
parent 301c23a588
commit 12d9841433
3 changed files with 10 additions and 16 deletions
-6
View File
@@ -20,12 +20,6 @@ bool random_bytes(uint8_t *data, size_t len) {
return true;
}
Mutex::Mutex() { handle_ = xSemaphoreCreateMutex(); }
Mutex::~Mutex() {}
void Mutex::lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
bool Mutex::try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
void Mutex::unlock() { xSemaphoreGive(this->handle_); }
// only affects the executing core
// so should not be used as a mutex lock, only to get accurate timing
IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
-6
View File
@@ -15,12 +15,6 @@ bool random_bytes(uint8_t *data, size_t len) {
return true;
}
Mutex::Mutex() { handle_ = xSemaphoreCreateMutex(); }
Mutex::~Mutex() {}
void Mutex::lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
bool Mutex::try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
void Mutex::unlock() { xSemaphoreGive(this->handle_); }
// only affects the executing core
// so should not be used as a mutex lock, only to get accurate timing
IRAM_ATTR InterruptLock::InterruptLock() { portDISABLE_INTERRUPTS(); }
+10 -4
View File
@@ -1876,6 +1876,16 @@ class Mutex {
void lock() {}
bool try_lock() { return true; }
void unlock() {}
#elif defined(USE_ESP32) || defined(USE_LIBRETINY)
// FreeRTOS platforms: inline to avoid out-of-line call overhead.
Mutex() { handle_ = xSemaphoreCreateMutex(); }
~Mutex() = default;
void lock() { xSemaphoreTake(this->handle_, portMAX_DELAY); }
bool try_lock() { return xSemaphoreTake(this->handle_, 0) == pdTRUE; }
void unlock() { xSemaphoreGive(this->handle_); }
private:
SemaphoreHandle_t handle_;
#else
Mutex();
~Mutex();
@@ -1884,13 +1894,9 @@ class Mutex {
void unlock();
private:
#if defined(USE_ESP32) || defined(USE_LIBRETINY)
SemaphoreHandle_t handle_;
#else
// d-pointer to store private data on new platforms
void *handle_; // NOLINT(clang-diagnostic-unused-private-field)
#endif
#endif // single-threaded check
};
/** Helper class that wraps a mutex with a RAII-style API.