107 lines
2.3 KiB
C++
107 lines
2.3 KiB
C++
#ifndef FREERTOS_CPP_MUTEX_HPP
|
|
#define FREERTOS_CPP_MUTEX_HPP
|
|
|
|
#include <type_traits>
|
|
|
|
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
|