use critical section in exitRealtime

the critical section ensures that cache clearing is performed as an atomic operation without task switch
This commit is contained in:
Frank
2025-12-22 00:20:34 +01:00
parent 50cc6f4c28
commit af8eba6dfa

View File

@@ -154,6 +154,9 @@ void notify(byte callMode, bool followUp)
static Segment* theMainSeg = nullptr; static Segment* theMainSeg = nullptr;
static int theMainSegLength = 0; static int theMainSegLength = 0;
static int theStripLength = 0; static int theStripLength = 0;
#ifdef ARDUINO_ARCH_ESP32
static portMUX_TYPE critical_lock = portMUX_INITIALIZER_UNLOCKED; // to make cache clearing an atomic operation
#endif
void realtimeLock(uint32_t timeoutMs, byte md) void realtimeLock(uint32_t timeoutMs, byte md)
{ {
@@ -236,13 +239,15 @@ void exitRealtime() {
strip.show(); // possible fix for #3589 strip.show(); // possible fix for #3589
} }
// WLEDMM invalide cached main segment pointer and length // WLEDMM invalide cached main segment pointer and length
if (esp32SemTake(busDrawMux, 200) == pdTRUE) { #ifdef ARDUINO_ARCH_ESP32
// WLEDMM protect against parallel cache updates from different tasks portENTER_CRITICAL(&critical_lock); // critical section to make cache reset atomic and thread-safe
#endif
theMainSeg = nullptr; theMainSeg = nullptr;
theMainSegLength = 0; theMainSegLength = 0;
theStripLength = 0; theStripLength = 0;
esp32SemGive(busDrawMux); #ifdef ARDUINO_ARCH_ESP32
} portEXIT_CRITICAL(&critical_lock); // end of critical section
#endif
busses.invalidateCache(false); // WLEDMM busses.invalidateCache(false); // WLEDMM
USER_PRINTLN(F("exitRealtime() realtime mode ended.")); USER_PRINTLN(F("exitRealtime() realtime mode ended."));
updateInterfaces(CALL_MODE_WS_SEND); updateInterfaces(CALL_MODE_WS_SEND);