From 8a9c60faeb531f3aad3f6ad063d78348658d8ce1 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sun, 28 Dec 2025 11:25:44 +0100 Subject: [PATCH 1/3] Split off RecursiveMutex from Mutex --- .../cyd-2432s024c/Source/devices/SdCard.cpp | 3 +- .../cyd-2432s028r/Source/devices/SdCard.cpp | 3 +- .../cyd-2432s028rv3/Source/devices/SdCard.cpp | 3 +- .../cyd-2432s032c/Source/devices/SdCard.cpp | 3 +- .../Source/devices/St7701Display.h | 4 +- Devices/cyd-e32r28t/Source/devices/SdCard.cpp | 3 +- Devices/cyd-e32r32p/Source/devices/SdCard.cpp | 3 +- .../cyd-jc2432w328c/Source/devices/SdCard.cpp | 3 +- .../cyd-jc8048w550c/Source/devices/SdCard.cpp | 3 +- Devices/simulator/Source/LvglTask.cpp | 6 +- .../simulator/Source/hal/SimulatorSdCard.h | 4 +- .../Source/devices/SdCard.cpp | 3 +- .../Source/devices/SdCard.cpp | 3 +- Drivers/RgbDisplay/Source/RgbDisplay.h | 3 +- .../Include/Tactility/hal/gps/GpsDevice.h | 4 +- .../Include/Tactility/hal/gps/Satellites.h | 4 +- .../Tactility/hal/sdcard/SdmmcDevice.h | 9 +-- .../Include/Tactility/network/HttpServer.h | 4 +- .../Tactility/service/gps/GpsService.h | 3 +- .../Include/Tactility/service/loader/Loader.h | 3 +- Tactility/Private/Tactility/app/AppInstance.h | 2 +- Tactility/Private/Tactility/app/files/State.h | 4 +- .../Tactility/app/fileselection/State.h | 4 +- .../Private/Tactility/app/wifimanage/State.h | 4 +- .../Tactility/service/ServiceInstance.h | 2 +- .../service/development/DevelopmentService.h | 4 +- .../Tactility/service/espnow/EspNowService.h | 4 +- .../Tactility/service/gui/GuiService.h | 4 +- .../memorychecker/MemoryCheckerService.h | 4 +- .../service/screenshot/ScreenshotTask.h | 4 +- Tactility/Source/app/AppRegistration.cpp | 2 +- .../Source/app/i2cscanner/I2cScanner.cpp | 3 +- .../app/localesettings/LocaleSettings.cpp | 3 +- .../app/timedatesettings/TimeDateSettings.cpp | 3 +- Tactility/Source/hal/Device.cpp | 4 +- Tactility/Source/hal/spi/Spi.cpp | 4 +- Tactility/Source/lvgl/Statusbar.cpp | 19 +++-- .../Source/service/ServiceRegistration.cpp | 4 +- Tactility/Source/service/wifi/WifiEsp.cpp | 5 +- Tactility/Source/service/wifi/WifiMock.cpp | 4 +- TactilityC/Source/tt_lock.cpp | 9 ++- TactilityCore/Include/Tactility/Mutex.h | 40 +++++----- .../Include/Tactility/RecursiveMutex.h | 67 ++++++++++++++++ TactilityCore/Source/Mutex.cpp | 77 ------------------- Tests/TactilityCore/MutexTest.cpp | 8 +- 45 files changed, 185 insertions(+), 177 deletions(-) create mode 100644 TactilityCore/Include/Tactility/RecursiveMutex.h delete mode 100644 TactilityCore/Source/Mutex.cpp diff --git a/Devices/cyd-2432s024c/Source/devices/SdCard.cpp b/Devices/cyd-2432s024c/Source/devices/SdCard.cpp index 158d5eab4..ad79ca1b5 100644 --- a/Devices/cyd-2432s024c/Source/devices/SdCard.cpp +++ b/Devices/cyd-2432s024c/Source/devices/SdCard.cpp @@ -3,6 +3,7 @@ #define TAG "twodotfour_sdcard" #include +#include constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; @@ -16,7 +17,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SDCARD_SPI_HOST ); diff --git a/Devices/cyd-2432s028r/Source/devices/SdCard.cpp b/Devices/cyd-2432s028r/Source/devices/SdCard.cpp index 03a263414..e0e4072a8 100644 --- a/Devices/cyd-2432s028r/Source/devices/SdCard.cpp +++ b/Devices/cyd-2432s028r/Source/devices/SdCard.cpp @@ -1,6 +1,7 @@ #include "SdCard.h" #include #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -11,7 +12,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI3_HOST ); diff --git a/Devices/cyd-2432s028rv3/Source/devices/SdCard.cpp b/Devices/cyd-2432s028rv3/Source/devices/SdCard.cpp index 03a263414..e0e4072a8 100644 --- a/Devices/cyd-2432s028rv3/Source/devices/SdCard.cpp +++ b/Devices/cyd-2432s028rv3/Source/devices/SdCard.cpp @@ -1,6 +1,7 @@ #include "SdCard.h" #include #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -11,7 +12,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI3_HOST ); diff --git a/Devices/cyd-2432s032c/Source/devices/SdCard.cpp b/Devices/cyd-2432s032c/Source/devices/SdCard.cpp index 01bdd7bbb..84360cfae 100644 --- a/Devices/cyd-2432s032c/Source/devices/SdCard.cpp +++ b/Devices/cyd-2432s032c/Source/devices/SdCard.cpp @@ -2,6 +2,7 @@ #include #include +#include constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; @@ -15,7 +16,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SDCARD_SPI_HOST ); diff --git a/Devices/cyd-4848s040c/Source/devices/St7701Display.h b/Devices/cyd-4848s040c/Source/devices/St7701Display.h index c2ee8e293..e0eae135d 100644 --- a/Devices/cyd-4848s040c/Source/devices/St7701Display.h +++ b/Devices/cyd-4848s040c/Source/devices/St7701Display.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -21,7 +21,7 @@ class St7701Display final : public EspLcdDisplay { public: - St7701Display() : EspLcdDisplay(std::make_shared(tt::Mutex::Type::Recursive)) {} + St7701Display() : EspLcdDisplay(std::make_shared()) {} std::string getName() const override { return "ST7701S"; } diff --git a/Devices/cyd-e32r28t/Source/devices/SdCard.cpp b/Devices/cyd-e32r28t/Source/devices/SdCard.cpp index 8b2a210d0..86f08b1c4 100644 --- a/Devices/cyd-e32r28t/Source/devices/SdCard.cpp +++ b/Devices/cyd-e32r28t/Source/devices/SdCard.cpp @@ -1,5 +1,6 @@ #include "SdCard.h" #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -10,7 +11,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI3_HOST ); diff --git a/Devices/cyd-e32r32p/Source/devices/SdCard.cpp b/Devices/cyd-e32r32p/Source/devices/SdCard.cpp index d73563c6d..a86ef14e8 100644 --- a/Devices/cyd-e32r32p/Source/devices/SdCard.cpp +++ b/Devices/cyd-e32r32p/Source/devices/SdCard.cpp @@ -1,5 +1,6 @@ #include "SdCard.h" #include +#include using tt::hal::sdcard::SpiSdCardDevice; using SdCardDevice = tt::hal::sdcard::SdCardDevice; @@ -11,7 +12,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, // MISO override: leave NC GPIO_NUM_NC, // SCLK override: leave NC SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SD_SPI_HOST // SPI host for SD card (SPI3_HOST) ); diff --git a/Devices/cyd-jc2432w328c/Source/devices/SdCard.cpp b/Devices/cyd-jc2432w328c/Source/devices/SdCard.cpp index 01bdd7bbb..84360cfae 100644 --- a/Devices/cyd-jc2432w328c/Source/devices/SdCard.cpp +++ b/Devices/cyd-jc2432w328c/Source/devices/SdCard.cpp @@ -2,6 +2,7 @@ #include #include +#include constexpr auto SDCARD_SPI_HOST = SPI3_HOST; constexpr auto SDCARD_PIN_CS = GPIO_NUM_5; @@ -15,7 +16,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SDCARD_SPI_HOST ); diff --git a/Devices/cyd-jc8048w550c/Source/devices/SdCard.cpp b/Devices/cyd-jc8048w550c/Source/devices/SdCard.cpp index 8a64a5ad6..153440cf4 100644 --- a/Devices/cyd-jc8048w550c/Source/devices/SdCard.cpp +++ b/Devices/cyd-jc8048w550c/Source/devices/SdCard.cpp @@ -2,6 +2,7 @@ #include #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -12,7 +13,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI2_HOST ); diff --git a/Devices/simulator/Source/LvglTask.cpp b/Devices/simulator/Source/LvglTask.cpp index 06074c6fb..daa2f8a1c 100644 --- a/Devices/simulator/Source/LvglTask.cpp +++ b/Devices/simulator/Source/LvglTask.cpp @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include @@ -10,8 +10,8 @@ #define TAG "lvgl_task" // Mutex for LVGL drawing -static tt::Mutex lvgl_mutex(tt::Mutex::Type::Recursive); -static tt::Mutex task_mutex(tt::Mutex::Type::Recursive); +static tt::RecursiveMutex lvgl_mutex; +static tt::RecursiveMutex task_mutex; static uint32_t task_max_sleep_ms = 10; // Mutex for LVGL task state (to modify task_running state) diff --git a/Devices/simulator/Source/hal/SimulatorSdCard.h b/Devices/simulator/Source/hal/SimulatorSdCard.h index 3d3bbbaf3..796a35fcd 100644 --- a/Devices/simulator/Source/hal/SimulatorSdCard.h +++ b/Devices/simulator/Source/hal/SimulatorSdCard.h @@ -1,7 +1,7 @@ #pragma once #include "Tactility/hal/sdcard/SdCardDevice.h" -#include +#include #include using tt::hal::sdcard::SdCardDevice; @@ -16,7 +16,7 @@ class SimulatorSdCard final : public SdCardDevice { SimulatorSdCard() : SdCardDevice(MountBehaviour::AtBoot), state(State::Unmounted), - lock(std::make_shared(tt::Mutex::Type::Recursive)) + lock(std::make_shared()) {} std::string getName() const override { return "Mock SD Card"; } diff --git a/Devices/waveshare-s3-lcd-13/Source/devices/SdCard.cpp b/Devices/waveshare-s3-lcd-13/Source/devices/SdCard.cpp index e0f2c39c8..b2c81f671 100644 --- a/Devices/waveshare-s3-lcd-13/Source/devices/SdCard.cpp +++ b/Devices/waveshare-s3-lcd-13/Source/devices/SdCard.cpp @@ -2,6 +2,7 @@ #include #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -12,7 +13,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI3_HOST ); diff --git a/Devices/waveshare-s3-touch-lcd-128/Source/devices/SdCard.cpp b/Devices/waveshare-s3-touch-lcd-128/Source/devices/SdCard.cpp index cd0d08a80..d9adcbdea 100644 --- a/Devices/waveshare-s3-touch-lcd-128/Source/devices/SdCard.cpp +++ b/Devices/waveshare-s3-touch-lcd-128/Source/devices/SdCard.cpp @@ -2,6 +2,7 @@ #include #include +#include using tt::hal::sdcard::SpiSdCardDevice; @@ -12,7 +13,7 @@ std::shared_ptr createSdCard() { GPIO_NUM_NC, GPIO_NUM_NC, SdCardDevice::MountBehaviour::AtBoot, - std::make_shared(tt::Mutex::Type::Recursive), + std::make_shared(), std::vector(), SPI3_HOST ); diff --git a/Drivers/RgbDisplay/Source/RgbDisplay.h b/Drivers/RgbDisplay/Source/RgbDisplay.h index 7c6ebc1f3..bbfb0a66a 100644 --- a/Drivers/RgbDisplay/Source/RgbDisplay.h +++ b/Drivers/RgbDisplay/Source/RgbDisplay.h @@ -1,13 +1,14 @@ #pragma once #include +#include #include #include #include class RgbDisplay final : public tt::hal::display::DisplayDevice { - std::shared_ptr lock = std::make_shared(tt::Mutex::Type::Recursive); + std::shared_ptr lock = std::make_shared(); public: diff --git a/Tactility/Include/Tactility/hal/gps/GpsDevice.h b/Tactility/Include/Tactility/hal/gps/GpsDevice.h index 86e9373b8..d56a95b00 100644 --- a/Tactility/Include/Tactility/hal/gps/GpsDevice.h +++ b/Tactility/Include/Tactility/hal/gps/GpsDevice.h @@ -4,7 +4,7 @@ #include "GpsConfiguration.h" #include "Satellites.h" -#include +#include #include #include @@ -47,7 +47,7 @@ class GpsDevice : public Device { }; const GpsConfiguration configuration; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::unique_ptr _Nullable thread; bool threadInterrupted = false; std::vector ggaSubscriptions; diff --git a/Tactility/Include/Tactility/hal/gps/Satellites.h b/Tactility/Include/Tactility/hal/gps/Satellites.h index 781cb1e7f..f8442c314 100644 --- a/Tactility/Include/Tactility/hal/gps/Satellites.h +++ b/Tactility/Include/Tactility/hal/gps/Satellites.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include #include @@ -30,7 +30,7 @@ class SatelliteStorage { bool inUse = false; }; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::array records; uint16_t recycleTimeSeconds; uint16_t recentTimeSeconds; diff --git a/Tactility/Include/Tactility/hal/sdcard/SdmmcDevice.h b/Tactility/Include/Tactility/hal/sdcard/SdmmcDevice.h index 992d403f4..01dc79f8d 100644 --- a/Tactility/Include/Tactility/hal/sdcard/SdmmcDevice.h +++ b/Tactility/Include/Tactility/hal/sdcard/SdmmcDevice.h @@ -4,14 +4,13 @@ #include "SdCardDevice.h" +#include +#include #include - #include +#include #include #include -#include -#include -#include namespace tt::hal::sdcard { @@ -20,7 +19,7 @@ namespace tt::hal::sdcard { */ class SdmmcDevice final : public SdCardDevice { - std::shared_ptr mutex = std::make_shared(Mutex::Type::Recursive); + std::shared_ptr mutex = std::make_shared(); public: diff --git a/Tactility/Include/Tactility/network/HttpServer.h b/Tactility/Include/Tactility/network/HttpServer.h index 4a238b86e..c15fea931 100644 --- a/Tactility/Include/Tactility/network/HttpServer.h +++ b/Tactility/Include/Tactility/network/HttpServer.h @@ -2,7 +2,7 @@ #ifdef ESP_PLATFORM #include -#include +#include #include namespace tt::network { @@ -33,7 +33,7 @@ class HttpServer { std::vector handlers; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; httpd_handle_t server = nullptr; bool startInternal(); diff --git a/Tactility/Include/Tactility/service/gps/GpsService.h b/Tactility/Include/Tactility/service/gps/GpsService.h index 5d7b4bd0f..6ea211a47 100644 --- a/Tactility/Include/Tactility/service/gps/GpsService.h +++ b/Tactility/Include/Tactility/service/gps/GpsService.h @@ -1,6 +1,7 @@ #pragma once #include "Tactility/Mutex.h" +#include "Tactility/RecursiveMutex.h" #include "Tactility/PubSub.h" #include "Tactility/hal/gps/GpsDevice.h" #include "Tactility/service/Service.h" @@ -20,7 +21,7 @@ class GpsService final : public Service { minmea_sentence_rmc rmcRecord; TickType_t rmcTime = 0; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; Mutex stateMutex; std::vector deviceRecords; std::shared_ptr> statePubSub = std::make_shared>(); diff --git a/Tactility/Include/Tactility/service/loader/Loader.h b/Tactility/Include/Tactility/service/loader/Loader.h index 7a3f8d184..9693c1368 100644 --- a/Tactility/Include/Tactility/service/loader/Loader.h +++ b/Tactility/Include/Tactility/service/loader/Loader.h @@ -5,6 +5,7 @@ #include #include #include +#include #include #include @@ -26,7 +27,7 @@ class LoaderService final : public Service { private: std::shared_ptr> pubsubExternal = std::make_shared>(); - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::vector> appStack; app::LaunchId nextLaunchId = 0; diff --git a/Tactility/Private/Tactility/app/AppInstance.h b/Tactility/Private/Tactility/app/AppInstance.h index 3bd9620da..c3416d126 100644 --- a/Tactility/Private/Tactility/app/AppInstance.h +++ b/Tactility/Private/Tactility/app/AppInstance.h @@ -25,7 +25,7 @@ enum class State { */ class AppInstance : public AppContext { - Mutex mutex = Mutex(Mutex::Type::Normal); + Mutex mutex; const std::shared_ptr manifest; State state = State::Initial; LaunchId launchId; diff --git a/Tactility/Private/Tactility/app/files/State.h b/Tactility/Private/Tactility/app/files/State.h index 5f2deab50..ffc33e283 100644 --- a/Tactility/Private/Tactility/app/files/State.h +++ b/Tactility/Private/Tactility/app/files/State.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -20,7 +20,7 @@ class State final { private: - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::vector dir_entries; std::string current_path; std::string selected_child_entry; diff --git a/Tactility/Private/Tactility/app/fileselection/State.h b/Tactility/Private/Tactility/app/fileselection/State.h index 15ad6f9f4..a29f770c9 100644 --- a/Tactility/Private/Tactility/app/fileselection/State.h +++ b/Tactility/Private/Tactility/app/fileselection/State.h @@ -1,6 +1,6 @@ #pragma once -#include +#include #include #include @@ -10,7 +10,7 @@ namespace tt::app::fileselection { class State final { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::vector dir_entries; std::string current_path; std::string selected_child_entry; diff --git a/Tactility/Private/Tactility/app/wifimanage/State.h b/Tactility/Private/Tactility/app/wifimanage/State.h index 5393944e0..f0a95bcd9 100644 --- a/Tactility/Private/Tactility/app/wifimanage/State.h +++ b/Tactility/Private/Tactility/app/wifimanage/State.h @@ -1,7 +1,7 @@ #pragma once #include -#include +#include namespace tt::app::wifimanage { @@ -10,7 +10,7 @@ namespace tt::app::wifimanage { */ class State final { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; bool scanning = false; bool scannedAfterRadioOn = false; service::wifi::RadioState radioState; diff --git a/Tactility/Private/Tactility/service/ServiceInstance.h b/Tactility/Private/Tactility/service/ServiceInstance.h index 29628ffba..b37e14a0d 100644 --- a/Tactility/Private/Tactility/service/ServiceInstance.h +++ b/Tactility/Private/Tactility/service/ServiceInstance.h @@ -10,7 +10,7 @@ namespace tt::service { class ServiceInstance final : public ServiceContext { - Mutex mutex = Mutex(Mutex::Type::Normal); + Mutex mutex; std::shared_ptr manifest; std::shared_ptr service; State state = State::Stopped; diff --git a/Tactility/Private/Tactility/service/development/DevelopmentService.h b/Tactility/Private/Tactility/service/development/DevelopmentService.h index 2d0bb5fdf..0d74dbbd7 100644 --- a/Tactility/Private/Tactility/service/development/DevelopmentService.h +++ b/Tactility/Private/Tactility/service/development/DevelopmentService.h @@ -3,7 +3,7 @@ #include -#include +#include #include #include @@ -13,7 +13,7 @@ namespace tt::service::development { class DevelopmentService final : public Service { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::string deviceResponse; network::HttpServer httpServer = network::HttpServer( 6666, diff --git a/Tactility/Private/Tactility/service/espnow/EspNowService.h b/Tactility/Private/Tactility/service/espnow/EspNowService.h index ef2d1ce9a..d3478240f 100644 --- a/Tactility/Private/Tactility/service/espnow/EspNowService.h +++ b/Tactility/Private/Tactility/service/espnow/EspNowService.h @@ -9,7 +9,7 @@ #include #include -#include +#include #include @@ -27,7 +27,7 @@ class EspNowService final : public Service { bool success; }; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::vector subscriptions; ReceiverSubscription lastSubscriptionId = 0; bool enabled = false; diff --git a/Tactility/Private/Tactility/service/gui/GuiService.h b/Tactility/Private/Tactility/service/gui/GuiService.h index f90e4c695..8cdccfa15 100644 --- a/Tactility/Private/Tactility/service/gui/GuiService.h +++ b/Tactility/Private/Tactility/service/gui/GuiService.h @@ -2,7 +2,7 @@ #include #include -#include +#include #include #include #include @@ -21,7 +21,7 @@ class GuiService final : public Service { // Thread and lock Thread* thread = nullptr; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; PubSub::SubscriptionHandle loader_pubsub_subscription = nullptr; // Layers and Canvas diff --git a/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h b/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h index b85ff40a4..35a401adc 100644 --- a/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h +++ b/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h @@ -2,7 +2,7 @@ #include "Tactility/service/Service.h" -#include +#include #include namespace tt::service::memorychecker { @@ -13,7 +13,7 @@ namespace tt::service::memorychecker { */ class MemoryCheckerService final : public Service { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; Timer timer = Timer(Timer::Type::Periodic, [this] { onTimerUpdate(); }); // LVGL Statusbar icon diff --git a/Tactility/Private/Tactility/service/screenshot/ScreenshotTask.h b/Tactility/Private/Tactility/service/screenshot/ScreenshotTask.h index 7015a5fa5..f2cce507e 100644 --- a/Tactility/Private/Tactility/service/screenshot/ScreenshotTask.h +++ b/Tactility/Private/Tactility/service/screenshot/ScreenshotTask.h @@ -5,7 +5,7 @@ #pragma once #include -#include +#include namespace tt::service::screenshot { @@ -22,7 +22,7 @@ class ScreenshotTask { }; Thread* thread = nullptr; - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; bool interrupted = false; bool finished = false; ScreenshotTaskWork work; diff --git a/Tactility/Source/app/AppRegistration.cpp b/Tactility/Source/app/AppRegistration.cpp index 8c6e7bc33..897546c6e 100644 --- a/Tactility/Source/app/AppRegistration.cpp +++ b/Tactility/Source/app/AppRegistration.cpp @@ -13,7 +13,7 @@ namespace tt::app { typedef std::unordered_map> AppManifestMap; static AppManifestMap app_manifest_map; -static Mutex hash_mutex(Mutex::Type::Normal); +static Mutex hash_mutex; void addAppManifest(const AppManifest& manifest) { TT_LOG_I(TAG, "Registering manifest %s", manifest.appId.c_str()); diff --git a/Tactility/Source/app/i2cscanner/I2cScanner.cpp b/Tactility/Source/app/i2cscanner/I2cScanner.cpp index 6933ad51a..9e437316a 100644 --- a/Tactility/Source/app/i2cscanner/I2cScanner.cpp +++ b/Tactility/Source/app/i2cscanner/I2cScanner.cpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -24,7 +25,7 @@ class I2cScannerApp final : public App { static constexpr auto* STOP_SCAN_TEXT = "Stop scan"; // Core - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::unique_ptr scanTimer = nullptr; // State ScanState scanState = ScanStateInitial; diff --git a/Tactility/Source/app/localesettings/LocaleSettings.cpp b/Tactility/Source/app/localesettings/LocaleSettings.cpp index 8a01bf533..e35775434 100644 --- a/Tactility/Source/app/localesettings/LocaleSettings.cpp +++ b/Tactility/Source/app/localesettings/LocaleSettings.cpp @@ -1,4 +1,5 @@ #include +#include #include #include #include @@ -26,7 +27,7 @@ extern const AppManifest manifest; class LocaleSettingsApp final : public App { tt::i18n::TextResources textResources = tt::i18n::TextResources(TEXT_RESOURCE_PATH); - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; lv_obj_t* timeZoneLabel = nullptr; lv_obj_t* regionLabel = nullptr; lv_obj_t* languageDropdown = nullptr; diff --git a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp index 1c4117e13..3b3e13f45 100644 --- a/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp +++ b/Tactility/Source/app/timedatesettings/TimeDateSettings.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -14,7 +15,7 @@ extern const AppManifest manifest; class TimeDateSettingsApp final : public App { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; static void onTimeFormatChanged(lv_event_t* event) { auto* widget = lv_event_get_target_obj(event); diff --git a/Tactility/Source/hal/Device.cpp b/Tactility/Source/hal/Device.cpp index 75890b433..66836ea4a 100644 --- a/Tactility/Source/hal/Device.cpp +++ b/Tactility/Source/hal/Device.cpp @@ -1,12 +1,12 @@ #include "Tactility/hal/Device.h" -#include +#include #include namespace tt::hal { std::vector> devices; -Mutex mutex = Mutex(Mutex::Type::Recursive); +RecursiveMutex mutex; static Device::Id nextId = 0; #define TAG "devices" diff --git a/Tactility/Source/hal/spi/Spi.cpp b/Tactility/Source/hal/spi/Spi.cpp index 01553ebee..a5138a155 100644 --- a/Tactility/Source/hal/spi/Spi.cpp +++ b/Tactility/Source/hal/spi/Spi.cpp @@ -1,6 +1,6 @@ #include "Tactility/hal/spi/Spi.h" -#include +#include namespace tt::hal::spi { @@ -24,7 +24,7 @@ bool init(const std::vector& configurations) { if (configuration.lock != nullptr) { data.lock = configuration.lock; } else { - data.lock = std::make_shared(Mutex::Type::Recursive); + data.lock = std::make_shared(); } } diff --git a/Tactility/Source/lvgl/Statusbar.cpp b/Tactility/Source/lvgl/Statusbar.cpp index 0c64cc963..bc918562d 100644 --- a/Tactility/Source/lvgl/Statusbar.cpp +++ b/Tactility/Source/lvgl/Statusbar.cpp @@ -1,23 +1,22 @@ #define LV_USE_PRIVATE_API 1 // For actual lv_obj_t declaration -#include "Tactility/lvgl/Statusbar.h" - -#include "Tactility/lvgl/Style.h" -#include "Tactility/lvgl/LvglSync.h" +#include +#include #include -#include +#include +#include +#include #include -#include -#include +#include #include +#include #include -#include namespace tt::lvgl { -#define TAG "statusbar" +constexpr auto TAG = "statusbar"; static void onUpdateTime(); @@ -28,7 +27,7 @@ struct StatusbarIcon { }; struct StatusbarData { - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; std::shared_ptr> pubsub = std::make_shared>(); StatusbarIcon icons[STATUSBAR_ICON_LIMIT] = {}; Timer* time_update_timer = new Timer(Timer::Type::Once, [] { onUpdateTime(); }); diff --git a/Tactility/Source/service/ServiceRegistration.cpp b/Tactility/Source/service/ServiceRegistration.cpp index 0d1bc4661..46fc65718 100644 --- a/Tactility/Source/service/ServiceRegistration.cpp +++ b/Tactility/Source/service/ServiceRegistration.cpp @@ -17,8 +17,8 @@ typedef std::unordered_map> Servic static ManifestMap service_manifest_map; static ServiceInstanceMap service_instance_map; -static Mutex manifest_mutex(Mutex::Type::Normal); -static Mutex instance_mutex(Mutex::Type::Normal); +static Mutex manifest_mutex; +static Mutex instance_mutex; void addService(std::shared_ptr manifest, bool autoStart) { assert(manifest != nullptr); diff --git a/Tactility/Source/service/wifi/WifiEsp.cpp b/Tactility/Source/service/wifi/WifiEsp.cpp index b72252d61..ab0dcf6cd 100644 --- a/Tactility/Source/service/wifi/WifiEsp.cpp +++ b/Tactility/Source/service/wifi/WifiEsp.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -48,8 +49,8 @@ class Wifi { public: /** @brief Locking mechanism for modifying the Wifi instance */ - Mutex radioMutex = Mutex(Mutex::Type::Recursive); - Mutex dataMutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex radioMutex; + RecursiveMutex dataMutex; std::unique_ptr autoConnectTimer; /** @brief The public event bus */ std::shared_ptr> pubsub = std::make_shared>(); diff --git a/Tactility/Source/service/wifi/WifiMock.cpp b/Tactility/Source/service/wifi/WifiMock.cpp index 71d1193dd..d559936ae 100644 --- a/Tactility/Source/service/wifi/WifiMock.cpp +++ b/Tactility/Source/service/wifi/WifiMock.cpp @@ -4,8 +4,8 @@ #include #include -#include #include +#include #include #include @@ -15,7 +15,7 @@ constexpr auto* TAG = "Wifi"; struct Wifi { /** @brief Locking mechanism for modifying the Wifi instance */ - Mutex mutex = Mutex(Mutex::Type::Recursive); + RecursiveMutex mutex; /** @brief The public event bus */ std::shared_ptr> pubsub = std::make_shared>(); /** @brief The internal message queue */ diff --git a/TactilityC/Source/tt_lock.cpp b/TactilityC/Source/tt_lock.cpp index 1757b9ffc..25ad8e5fe 100644 --- a/TactilityC/Source/tt_lock.cpp +++ b/TactilityC/Source/tt_lock.cpp @@ -1,7 +1,8 @@ -#include -#include #include +#include #include +#include +#include #define HANDLE_AS_LOCK(handle) (static_cast(handle)->lock) @@ -11,10 +12,10 @@ LockHandle tt_lock_alloc_mutex(TtMutexType type) { auto* lock_holder = new LockHolder(); switch (type) { case MutexTypeNormal: - lock_holder->lock = std::make_shared(tt::Mutex::Type::Normal); + lock_holder->lock = std::make_shared(); break; case MutexTypeRecursive: - lock_holder->lock = std::make_shared(tt::Mutex::Type::Recursive); + lock_holder->lock = std::make_shared(); break; default: tt_crash("Type not supported"); diff --git a/TactilityCore/Include/Tactility/Mutex.h b/TactilityCore/Include/Tactility/Mutex.h index 8642fc463..ad0acc0e1 100644 --- a/TactilityCore/Include/Tactility/Mutex.h +++ b/TactilityCore/Include/Tactility/Mutex.h @@ -1,15 +1,16 @@ /** - * @file mutex.h + * @file Mutex.h * Mutex */ #pragma once -#include "Check.h" #include "Lock.h" #include "RtosCompatSemaphore.h" #include "Thread.h" #include "kernel/Kernel.h" + #include +#include namespace tt { @@ -19,16 +20,6 @@ namespace tt { */ class Mutex final : public Lock { -public: - /** - * A "Normal" mutex can only be locked once. Even from within the same task/thread. - * A "Recursive" mutex can be locked again from the same task/thread. - */ - enum class Type { - Normal, - Recursive, - }; - private: struct SemaphoreHandleDeleter { @@ -38,29 +29,40 @@ class Mutex final : public Lock { } }; - std::unique_ptr, SemaphoreHandleDeleter> handle; - Type type; + std::unique_ptr, SemaphoreHandleDeleter> handle = std::unique_ptr, SemaphoreHandleDeleter>(xSemaphoreCreateMutex()); public: using Lock::lock; - explicit Mutex(Type type = Type::Normal); + explicit Mutex() { + assert(handle != nullptr); + } + ~Mutex() override = default; /** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired. * @param[in] timeout * @return success result */ - bool lock(TickType_t timeout) const override; + bool lock(TickType_t timeout) const override { + assert(!kernel::isIsr()); + return xSemaphoreTake(handle.get(), timeout) == pdPASS; + } /** Attempt to unlock the mutex. * @return success result */ - bool unlock() const override; + bool unlock() const override { + assert(!kernel::isIsr()); + return xSemaphoreGive(handle.get()) == pdPASS; + } /** @return the owner of the thread */ - ThreadId getOwner() const; + ThreadId getOwner() const { + assert(!kernel::isIsr()); + return xSemaphoreGetMutexHolder(handle.get()); + } }; -} // namespace +} // namespace tt diff --git a/TactilityCore/Include/Tactility/RecursiveMutex.h b/TactilityCore/Include/Tactility/RecursiveMutex.h new file mode 100644 index 000000000..21b2a3fb6 --- /dev/null +++ b/TactilityCore/Include/Tactility/RecursiveMutex.h @@ -0,0 +1,67 @@ +/** + * @file RecursiveMutex.h + * Mutex + */ +#pragma once + +#include "Lock.h" +#include "RtosCompatSemaphore.h" +#include "Thread.h" +#include "kernel/Kernel.h" +#include +#include + +namespace tt { + +/** + * Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex + * Cannot be used in IRQ mode (within ISR context) + */ +class RecursiveMutex final : public Lock { + +private: + + struct SemaphoreHandleDeleter { + void operator()(QueueHandle_t handleToDelete) { + assert(!kernel::isIsr()); + vSemaphoreDelete(handleToDelete); + } + }; + + std::unique_ptr, SemaphoreHandleDeleter> handle = std::unique_ptr, SemaphoreHandleDeleter>(xSemaphoreCreateRecursiveMutex()); + +public: + + using Lock::lock; + + explicit RecursiveMutex() { + assert(handle != nullptr); + } + + ~RecursiveMutex() override = default; + + /** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired. + * @param[in] timeout + * @return success result + */ + bool lock(TickType_t timeout) const override { + assert(!kernel::isIsr()); + return xSemaphoreTakeRecursive(handle.get(), timeout) == pdPASS; + } + + /** Attempt to unlock the mutex. + * @return success result + */ + bool unlock() const override { + assert(!kernel::isIsr()); + return xSemaphoreGiveRecursive(handle.get()) == pdPASS; + } + + /** @return the owner of the thread */ + ThreadId getOwner() const { + assert(!kernel::isIsr()); + return xSemaphoreGetMutexHolder(handle.get()); + } +}; + +} // namespace diff --git a/TactilityCore/Source/Mutex.cpp b/TactilityCore/Source/Mutex.cpp deleted file mode 100644 index 0a6cdf193..000000000 --- a/TactilityCore/Source/Mutex.cpp +++ /dev/null @@ -1,77 +0,0 @@ -#include "Tactility/Mutex.h" - -#include "Tactility/Check.h" -#include "Tactility/CoreDefines.h" -#include "Tactility/Log.h" - -namespace tt { - -#define MUTEX_DEBUGGING false - -#if MUTEX_DEBUGGING -#define TAG "mutex" - void tt_mutex_info(Mutex mutex, const char* label) { - MutexData* data = (MutexData*)mutex; - if (data == NULL) { - TT_LOG_I(TAG, "mutex %s: is NULL", label); - } else { - TT_LOG_I(TAG, "mutex %s: handle=%0X type=%d owner=%0x", label, data->handle, data->type, tt_mutex_get_owner(mutex)); - } - } -#else -#define tt_mutex_info(mutex, text) -#endif - -static inline SemaphoreHandle_t createSemaphoreHandle(Mutex::Type type) { - switch (type) { - case Mutex::Type::Normal: - return xSemaphoreCreateMutex(); - case Mutex::Type::Recursive: - return xSemaphoreCreateRecursiveMutex(); - default: - tt_crash("Mutex type unknown/corrupted"); - } -} - -Mutex::Mutex(Type type) : handle(createSemaphoreHandle(type)), type(type) { - tt_mutex_info(data, "alloc"); - assert(handle != nullptr); -} - -bool Mutex::lock(TickType_t timeout) const { - assert(!kernel::isIsr()); - assert(handle != nullptr); - tt_mutex_info(mutex, "acquire"); - - switch (type) { - case Type::Normal: - return xSemaphoreTake(handle.get(), timeout) == pdPASS; - case Type::Recursive: - return xSemaphoreTakeRecursive(handle.get(), timeout) == pdPASS; - default: - tt_crash(); - } -} - -bool Mutex::unlock() const { - assert(!kernel::isIsr()); - assert(handle != nullptr); - tt_mutex_info(mutex, "release"); - - switch (type) { - case Type::Normal: - return xSemaphoreGive(handle.get()) == pdPASS; - case Type::Recursive: - return xSemaphoreGiveRecursive(handle.get()) == pdPASS; - default: - tt_crash(); - } -} - -ThreadId Mutex::getOwner() const { - assert(!kernel::isIsr()); - assert(handle != nullptr); - return (ThreadId)xSemaphoreGetMutexHolder(handle.get()); -} - -} // namespace diff --git a/Tests/TactilityCore/MutexTest.cpp b/Tests/TactilityCore/MutexTest.cpp index 42227cf13..768f638cf 100644 --- a/Tests/TactilityCore/MutexTest.cpp +++ b/Tests/TactilityCore/MutexTest.cpp @@ -5,7 +5,7 @@ using namespace tt; TEST_CASE("a mutex can block a thread") { - auto mutex = Mutex(Mutex::Type::Normal); + auto mutex = Mutex(); mutex.lock(portMAX_DELAY); Thread thread = Thread( @@ -30,19 +30,19 @@ TEST_CASE("a mutex can block a thread") { } TEST_CASE("a Mutex can be locked exactly once") { - auto mutex = Mutex(Mutex::Type::Normal); + Mutex mutex; CHECK_EQ(mutex.lock(0), true); CHECK_EQ(mutex.lock(0), false); CHECK_EQ(mutex.unlock(), true); } TEST_CASE("unlocking a Mutex without locking returns false") { - auto mutex = Mutex(Mutex::Type::Normal); + Mutex mutex; CHECK_EQ(mutex.unlock(), false); } TEST_CASE("unlocking a Mutex twice returns false on the second attempt") { - auto mutex = Mutex(Mutex::Type::Normal); + Mutex mutex; CHECK_EQ(mutex.lock(0), true); CHECK_EQ(mutex.unlock(), true); CHECK_EQ(mutex.unlock(), false); From af2809d3eef0b29162f93cfc9e20b0e6665c0856 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sun, 28 Dec 2025 11:32:55 +0100 Subject: [PATCH 2/3] Fix --- Devices/cyd-4848s040c/Source/devices/St7701Display.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Devices/cyd-4848s040c/Source/devices/St7701Display.h b/Devices/cyd-4848s040c/Source/devices/St7701Display.h index e0eae135d..2ae12c4f0 100644 --- a/Devices/cyd-4848s040c/Source/devices/St7701Display.h +++ b/Devices/cyd-4848s040c/Source/devices/St7701Display.h @@ -21,7 +21,7 @@ class St7701Display final : public EspLcdDisplay { public: - St7701Display() : EspLcdDisplay(std::make_shared()) {} + St7701Display() : EspLcdDisplay(std::make_shared()) {} std::string getName() const override { return "ST7701S"; } From 7e867f2148c110ec45cd35d00c07d0f1105d8bd1 Mon Sep 17 00:00:00 2001 From: Ken Van Hoeylandt Date: Sun, 28 Dec 2025 11:35:42 +0100 Subject: [PATCH 3/3] Code quality --- .../Tactility/service/memorychecker/MemoryCheckerService.h | 4 ++-- TactilityCore/Include/Tactility/Mutex.h | 2 +- TactilityCore/Include/Tactility/RecursiveMutex.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h b/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h index 35a401adc..a8fef7a0b 100644 --- a/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h +++ b/Tactility/Private/Tactility/service/memorychecker/MemoryCheckerService.h @@ -2,7 +2,7 @@ #include "Tactility/service/Service.h" -#include +#include #include namespace tt::service::memorychecker { @@ -13,7 +13,7 @@ namespace tt::service::memorychecker { */ class MemoryCheckerService final : public Service { - RecursiveMutex mutex; + Mutex mutex; Timer timer = Timer(Timer::Type::Periodic, [this] { onTimerUpdate(); }); // LVGL Statusbar icon diff --git a/TactilityCore/Include/Tactility/Mutex.h b/TactilityCore/Include/Tactility/Mutex.h index ad0acc0e1..b69b48b31 100644 --- a/TactilityCore/Include/Tactility/Mutex.h +++ b/TactilityCore/Include/Tactility/Mutex.h @@ -15,7 +15,7 @@ namespace tt { /** - * Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex + * Wrapper for FreeRTOS xSemaphoreCreateMutex * Cannot be used in IRQ mode (within ISR context) */ class Mutex final : public Lock { diff --git a/TactilityCore/Include/Tactility/RecursiveMutex.h b/TactilityCore/Include/Tactility/RecursiveMutex.h index 21b2a3fb6..3d51522b6 100644 --- a/TactilityCore/Include/Tactility/RecursiveMutex.h +++ b/TactilityCore/Include/Tactility/RecursiveMutex.h @@ -1,6 +1,6 @@ /** * @file RecursiveMutex.h - * Mutex + * RecursiveMutex */ #pragma once @@ -14,7 +14,7 @@ namespace tt { /** - * Wrapper for FreeRTOS xSemaphoreCreateMutex and xSemaphoreCreateRecursiveMutex + * Wrapper for FreeRTOS xSemaphoreCreateRecursiveMutex * Cannot be used in IRQ mode (within ISR context) */ class RecursiveMutex final : public Lock {