#ifndef FREERTOS_CPP_MUTEX_HPP #define FREERTOS_CPP_MUTEX_HPP #include extern "C" { #include "FreeRTOS.h" #include "semphr.h" #include "task.h" } namespace freertos { struct StaticMutexStorage final { StaticSemaphore_t control {}; }; class Mutex final { public: explicit Mutex( StaticMutexStorage & storage ) noexcept : handle_ { xSemaphoreCreateMutexStatic( &storage.control ) } { } ~Mutex() noexcept { if( handle_ != nullptr ) { vSemaphoreDelete( handle_ ); } } Mutex( const Mutex & ) = delete; Mutex & operator=( const Mutex & ) = delete; Mutex( Mutex && ) = delete; Mutex & operator=( Mutex && ) = delete; [[nodiscard]] bool valid() const noexcept { return handle_ != nullptr; } [[nodiscard]] bool lock( TickType_t timeout ) noexcept { return handle_ != nullptr && xSemaphoreTake( handle_, timeout ) == pdPASS; } [[nodiscard]] bool unlock() noexcept { return handle_ != nullptr && xSemaphoreGive( handle_ ) == pdPASS; } [[nodiscard]] TaskHandle_t owner() const noexcept { return handle_ == nullptr ? nullptr : xSemaphoreGetMutexHolder( handle_ ); } [[nodiscard]] SemaphoreHandle_t native_handle() const noexcept { return handle_; } private: SemaphoreHandle_t handle_ {}; }; template< typename Lockable > class LockGuard final { public: explicit LockGuard( Lockable & lockable, TickType_t timeout ) noexcept : lockable_ { &lockable }, owns_ { lockable.lock( timeout ) } { } ~LockGuard() noexcept { if( owns_ ) { ( void ) lockable_->unlock(); } } LockGuard( const LockGuard & ) = delete; LockGuard & operator=( const LockGuard & ) = delete; LockGuard( LockGuard && ) = delete; LockGuard & operator=( LockGuard && ) = delete; [[nodiscard]] bool owns_lock() const noexcept { return owns_; } private: Lockable * const lockable_; const bool owns_; }; static_assert( !std::is_copy_constructible< Mutex >::value ); static_assert( !std::is_move_constructible< Mutex >::value ); static_assert( !std::is_copy_constructible< LockGuard< Mutex > >::value ); static_assert( !std::is_move_constructible< LockGuard< Mutex > >::value ); } // namespace freertos #endif