minor refactoring of critical sections

- define dummy macros for 8266, to avoid #ifdef ESP32
- small hint for readers who were not able to play arcade games in the 1980's ;-)
This commit is contained in:
Frank
2025-12-22 17:59:22 +01:00
parent 7459cbd2e2
commit 68a76ff442
2 changed files with 18 additions and 16 deletions

View File

@@ -11,7 +11,7 @@
#include <esp_timer.h> // WLEDMM to get esp_timer_get_time()
#include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h"
static portMUX_TYPE s_wled_strip_mux = portMUX_INITIALIZER_UNLOCKED; // to protect deleting Segment::_globalLeds
WLED_create_spinlock(ledsrgb_mux); // to protect deleting Segment::_globalLeds and Segment::ledsrgb
#endif
/*
@@ -117,18 +117,19 @@ void Segment::allocLeds() {
if ((size > 0) && (!ledsrgb || size > ledsrgbSize)) { //softhack dont allocate zero bytes
DEBUG_PRINTF("allocLeds (%d,%d to %d,%d), %u from %u\n", start, startY, stop, stopY, size, ledsrgb?ledsrgbSize:0);
// DONG - Valkyrie needs food, badly [Gauntlet, 1985]
// WLEDMM this looks a bit over-compilicated, but it makes the re-allocation step an atomic and threadsafe operation
CRGB* oldLedsRgb = ledsrgb;
portENTER_CRITICAL(&ledsrgb_mux);
ledsrgb = nullptr;
portEXIT_CRITICAL(&ledsrgb_mux);
if (oldLedsRgb) free(oldLedsRgb); // we need a bigger buffer, so free the old one first
CRGB* newLedsRgb = (CRGB*)calloc(1, size); // WLEDMM This is an OS call, so we should not wrap it in portEnterCRITICAL
#if defined(ARDUINO_ARCH_ESP32)
portENTER_CRITICAL(&s_wled_strip_mux);
#endif
ledsrgb = newLedsRgb;
#if defined(ARDUINO_ARCH_ESP32)
portEXIT_CRITICAL(&s_wled_strip_mux);
#endif
portENTER_CRITICAL(&ledsrgb_mux);
ledsrgb = newLedsRgb;
portEXIT_CRITICAL(&ledsrgb_mux);
ledsrgbSize = ledsrgb?size:0;
if (ledsrgb == nullptr) {
@@ -1885,18 +1886,14 @@ void WS2812FX::finalizeInit(void)
//initialize leds array. TBD: realloc if nr of leds change
if (Segment::_globalLeds) {
// DONG - Valkyrie is about to die
// DONG - Valkyrie is about to die [Gauntlet, 1985]
// this is a critical section that will be removed with PR #278 which removes _globalLeds
// problem: suspendStripService provides interlocking, but theres a window before service() observes it,
// and ESP32 is dual-core. A critical section closes that window so the pointer swap is atomic across cores.
CRGB* oldGLeds = Segment::_globalLeds;
#if defined(ARDUINO_ARCH_ESP32)
portENTER_CRITICAL(&s_wled_strip_mux);
#endif
portENTER_CRITICAL(&ledsrgb_mux);
Segment::_globalLeds = nullptr;
#if defined(ARDUINO_ARCH_ESP32)
portEXIT_CRITICAL(&s_wled_strip_mux);
#endif
portEXIT_CRITICAL(&ledsrgb_mux);
free(oldGLeds);
purgeSegments(true); // WLEDMM moved here, because it seems to improve stability.
}

View File

@@ -772,8 +772,9 @@ WLED_GLOBAL SemaphoreHandle_t busDrawMux _INIT(nullptr);
WLED_GLOBAL SemaphoreHandle_t segmentMux _INIT(nullptr);
#define esp32SemTake(mux,timeout) xSemaphoreTakeRecursive(mux, timeout) // convenience macro that expands to xSemaphoreTakeRecursive
#define esp32SemGive(mux) xSemaphoreGiveRecursive(mux) // convenience macro that expands to xSemaphoreGiveRecursive
#define WLED_create_spinlock(theSname) static portMUX_TYPE theSname = portMUX_INITIALIZER_UNLOCKED
#else
// dummy for 8266
// dummy semaphores for 8266
#ifndef pdTRUE
#define pdTRUE 1
#endif
@@ -782,6 +783,10 @@ WLED_GLOBAL SemaphoreHandle_t segmentMux _INIT(nullptr);
#endif
#define esp32SemTake(mux,timeout) (pdTRUE)
#define esp32SemGive(mux)
// dummy critical section for 8266
#define WLED_create_spinlock(sname)
#define portENTER_CRITICAL(sname)
#define portEXIT_CRITICAL(sname)
#endif
#ifndef ESP8266