87 lines
2.3 KiB
C++
87 lines
2.3 KiB
C++
#include <cassert>
|
|
#include <type_traits>
|
|
|
|
#include "freertos/mutex.hpp"
|
|
|
|
namespace
|
|
{
|
|
unsigned token;
|
|
unsigned takes;
|
|
unsigned gives;
|
|
unsigned deletes;
|
|
TickType_t last_timeout;
|
|
|
|
uint32_t guarded_path( freertos::Mutex & mutex, uint32_t path )
|
|
{
|
|
freertos::LockGuard< freertos::Mutex > guard { mutex, 9U };
|
|
assert( guard.owns_lock() );
|
|
assert( mutex.owner() == &token );
|
|
if( path == 0U ) return 10U;
|
|
if( path == 1U ) return 20U;
|
|
return 30U;
|
|
}
|
|
} // namespace
|
|
|
|
extern "C" TaskHandle_t xTaskGetCurrentTaskHandle()
|
|
{
|
|
return &token;
|
|
}
|
|
extern "C" SemaphoreHandle_t xSemaphoreCreateMutexStatic(
|
|
StaticSemaphore_t * storage )
|
|
{
|
|
*storage = MockSemaphore {};
|
|
return storage;
|
|
}
|
|
extern "C" BaseType_t xSemaphoreTake( SemaphoreHandle_t mutex,
|
|
TickType_t timeout )
|
|
{
|
|
++takes;
|
|
last_timeout = timeout;
|
|
if( mutex->locked != pdFALSE ) return pdFAIL;
|
|
mutex->locked = pdTRUE;
|
|
mutex->owner = xTaskGetCurrentTaskHandle();
|
|
return pdPASS;
|
|
}
|
|
extern "C" BaseType_t xSemaphoreGive( SemaphoreHandle_t mutex )
|
|
{
|
|
if( mutex->locked == pdFALSE ||
|
|
mutex->owner != xTaskGetCurrentTaskHandle() ) return pdFAIL;
|
|
++gives;
|
|
mutex->locked = pdFALSE;
|
|
mutex->owner = nullptr;
|
|
return pdPASS;
|
|
}
|
|
extern "C" TaskHandle_t xSemaphoreGetMutexHolder( SemaphoreHandle_t mutex )
|
|
{
|
|
return mutex->owner;
|
|
}
|
|
extern "C" void vSemaphoreDelete( SemaphoreHandle_t )
|
|
{
|
|
++deletes;
|
|
}
|
|
|
|
static_assert( !std::is_copy_constructible< freertos::Mutex >::value );
|
|
static_assert( !std::is_move_constructible<
|
|
freertos::LockGuard< freertos::Mutex > >::value );
|
|
|
|
int main()
|
|
{
|
|
freertos::StaticMutexStorage storage {};
|
|
{
|
|
freertos::Mutex mutex { storage };
|
|
assert( mutex.valid() && mutex.native_handle() == &storage.control );
|
|
for( uint32_t path = 0U; path < 3U; ++path )
|
|
{
|
|
assert( guarded_path( mutex, path ) == 10U + path * 10U );
|
|
assert( storage.control.locked == pdFALSE );
|
|
}
|
|
assert( takes == 3U && gives == 3U && last_timeout == 9U );
|
|
|
|
freertos::LockGuard< freertos::Mutex > outer { mutex, 0U };
|
|
assert( outer.owns_lock() );
|
|
freertos::LockGuard< freertos::Mutex > recursive_attempt { mutex, 0U };
|
|
assert( !recursive_attempt.owns_lock() );
|
|
}
|
|
assert( gives == 4U && deletes == 1U );
|
|
}
|