Files
lab-rv32i-freertos-mutex/tests/mutex_host.cpp
T
2026-07-21 19:14:19 +02:00

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 );
}