Kernel improvements (#485)
* **New Features** * Added public accessors for querying module/device start and ready state. * **Refactor** * Internal state moved to opaque internal objects; module/device/driver initializers now explicitly initialize internal pointers. * Lifecycle handling updated to construct/destruct internal state and use accessors. * **Tests** * Tests updated to use public accessors and explicit construct/destruct lifecycle calls. * **Chores** * Test build/include paths and small metadata updated.
This commit is contained in:
committed by
GitHub
parent
1757af859c
commit
79e43b093a
@@ -0,0 +1,86 @@
|
||||
#include "doctest.h"
|
||||
#include <tactility/concurrent/recursive_mutex.h>
|
||||
|
||||
TEST_CASE("recursive_mutex_construct and mutex_destruct should properly set the handle") {
|
||||
RecursiveMutex mutex = { 0 };
|
||||
recursive_mutex_construct(&mutex);
|
||||
CHECK_NE(mutex.handle, nullptr);
|
||||
recursive_mutex_destruct(&mutex);
|
||||
CHECK_EQ(mutex.handle, nullptr);
|
||||
}
|
||||
|
||||
TEST_CASE("recursive_mutex_is_locked should return true only when the mutex is locked") {
|
||||
RecursiveMutex mutex = { 0 };
|
||||
recursive_mutex_construct(&mutex);
|
||||
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), false);
|
||||
recursive_mutex_lock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), true);
|
||||
recursive_mutex_unlock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), false);
|
||||
|
||||
recursive_mutex_destruct(&mutex);
|
||||
}
|
||||
|
||||
TEST_CASE("recursive_mutex_is_locked can lock twice from the same thread") {
|
||||
RecursiveMutex mutex = { 0 };
|
||||
recursive_mutex_construct(&mutex);
|
||||
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), false);
|
||||
recursive_mutex_lock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), true);
|
||||
recursive_mutex_lock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), true);
|
||||
recursive_mutex_unlock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), true);
|
||||
recursive_mutex_unlock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), false);
|
||||
|
||||
recursive_mutex_destruct(&mutex);
|
||||
}
|
||||
|
||||
TEST_CASE("recursive_mutex_try_lock should lock multiple times from the same thread") {
|
||||
RecursiveMutex mutex = { 0 };
|
||||
recursive_mutex_construct(&mutex);
|
||||
|
||||
CHECK_EQ(recursive_mutex_try_lock(&mutex), true);
|
||||
CHECK_EQ(recursive_mutex_try_lock(&mutex), true);
|
||||
recursive_mutex_unlock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), true);
|
||||
recursive_mutex_unlock(&mutex);
|
||||
CHECK_EQ(recursive_mutex_is_locked(&mutex), false);
|
||||
|
||||
recursive_mutex_destruct(&mutex);
|
||||
}
|
||||
|
||||
TEST_CASE("recursive_mutex_lock in another task should block when a lock is active") {
|
||||
static int task_lock_counter = 0;
|
||||
RecursiveMutex mutex = { 0 };
|
||||
task_lock_counter = 0;
|
||||
|
||||
recursive_mutex_construct(&mutex);
|
||||
recursive_mutex_lock(&mutex);
|
||||
|
||||
TaskHandle_t task_handle;
|
||||
auto task_create_result = xTaskCreate(
|
||||
[](void* input) {
|
||||
RecursiveMutex* mutex_ptr = static_cast<RecursiveMutex*>(input);
|
||||
recursive_mutex_lock(mutex_ptr);
|
||||
task_lock_counter++;
|
||||
vTaskDelete(nullptr);
|
||||
},
|
||||
"mutex_test",
|
||||
2048,
|
||||
&mutex,
|
||||
0,
|
||||
&task_handle
|
||||
);
|
||||
|
||||
CHECK_EQ(task_create_result, pdPASS);
|
||||
CHECK_EQ(task_lock_counter, 0);
|
||||
|
||||
recursive_mutex_unlock(&mutex);
|
||||
vTaskDelay(2); // 1 is sufficient most of the time, but not always
|
||||
CHECK_EQ(task_lock_counter, 1);
|
||||
recursive_mutex_destruct(&mutex);
|
||||
}
|
||||
Reference in New Issue
Block a user