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