20std::atomic<int> g_tests_completed{0};
21std::atomic<int> g_tests_failed{0};
27void test_mutex_basic_lock_unlock(
void* ) {
28 klog::Info(
"=== Mutex Basic Lock/Unlock Test ===");
30 Mutex mtx(
"basic_test");
33 if (mtx.IsLockedByCurrentTask()) {
34 klog::Err(
"test_mutex_basic: FAIL — mutex locked before Lock()");
38 auto lock_result = mtx.Lock();
39 if (!lock_result.has_value()) {
40 klog::Err(
"test_mutex_basic: FAIL — Lock() returned error");
44 if (!mtx.IsLockedByCurrentTask()) {
46 "test_mutex_basic: FAIL — IsLockedByCurrentTask false after Lock");
50 auto unlock_result = mtx.UnLock();
51 if (!unlock_result.has_value()) {
52 klog::Err(
"test_mutex_basic: FAIL — UnLock() returned error");
56 if (mtx.IsLockedByCurrentTask()) {
58 "test_mutex_basic: FAIL — IsLockedByCurrentTask true after UnLock");
63 klog::Info(
"Mutex Basic Lock/Unlock Test: PASSED");
65 klog::Err(
"Mutex Basic Lock/Unlock Test: FAILED");
79 std::atomic<int> holder_locked{0};
80 std::atomic<int> holder_done{0};
83void trylock_holder(
void* arg) {
84 auto* ctx =
reinterpret_cast<TryLockArgs*
>(arg);
85 (void)ctx->mtx->
Lock();
86 ctx->holder_locked.store(1);
88 (void)ctx->mtx->UnLock();
89 ctx->holder_done.store(1);
93void test_mutex_trylock(
void* ) {
96 Mutex mtx(
"trylock_test");
99 auto try_result = mtx.TryLock();
100 if (!try_result.has_value()) {
101 klog::Err(
"test_mutex_trylock: FAIL — TryLock on free mutex failed");
109 auto holder = kstd::make_unique<TaskControlBlock>(
110 "TryLockHolder", 10, trylock_holder,
reinterpret_cast<void*
>(&ctx));
111 TaskManagerSingleton::instance().AddTask(std::move(holder));
114 while (timeout > 0 && ctx.holder_locked.load() == 0) {
119 if (ctx.holder_locked.load() != 1) {
120 klog::Err(
"test_mutex_trylock: FAIL — holder did not acquire lock");
123 auto try_result2 = mtx.TryLock();
124 if (try_result2.has_value()) {
125 klog::Err(
"test_mutex_trylock: FAIL — TryLock succeeded on held mutex");
132 while (timeout > 0 && ctx.holder_done.load() == 0) {
152struct ContentionArgs {
154 std::atomic<int>* counter;
157void contention_worker(
void* arg) {
158 auto* ctx =
reinterpret_cast<ContentionArgs*
>(arg);
159 for (
int i = 0; i < 5; ++i) {
160 (void)ctx->mtx->Lock();
161 int val = ctx->counter->load();
163 ctx->counter->store(val + 1);
164 (void)ctx->mtx->UnLock();
169void test_mutex_contention(
void* ) {
172 Mutex mtx(
"contention_test");
173 std::atomic<int> counter{0};
176 ContentionArgs ctx_a;
178 ctx_a.counter = &counter;
180 ContentionArgs ctx_b;
182 ctx_b.counter = &counter;
184 auto task_a = kstd::make_unique<TaskControlBlock>(
185 "ContentionA", 10, contention_worker,
reinterpret_cast<void*
>(&ctx_a));
186 auto task_b = kstd::make_unique<TaskControlBlock>(
187 "ContentionB", 10, contention_worker,
reinterpret_cast<void*
>(&ctx_b));
189 TaskManagerSingleton::instance().AddTask(std::move(task_a));
190 TaskManagerSingleton::instance().AddTask(std::move(task_b));
193 while (timeout > 0 && counter.load() < 10) {
198 if (counter.load() != 10) {
199 klog::Err(
"test_mutex_contention: FAIL — counter={}, expected 10",
207 klog::Err(
"Mutex Contention Test: FAILED");
221 std::atomic<int>* sequence;
225void ordering_first(
void* arg) {
226 auto* ctx =
reinterpret_cast<OrderingArgs*
>(arg);
227 (void)ctx->mtx->Lock();
229 ctx->sequence->store(ctx->task_id);
230 (void)ctx->mtx->UnLock();
234void ordering_second(
void* arg) {
235 auto* ctx =
reinterpret_cast<OrderingArgs*
>(arg);
237 (void)ctx->mtx->Lock();
238 int prev = ctx->sequence->load();
239 ctx->sequence->store(ctx->task_id);
240 (void)ctx->mtx->UnLock();
242 klog::Err(
"ordering_second: first writer was {} not 1", prev);
247void test_mutex_ordering(
void* ) {
250 Mutex mtx(
"ordering_test");
251 std::atomic<int> sequence{0};
254 OrderingArgs ctx_first;
255 ctx_first.mtx = &mtx;
256 ctx_first.sequence = &sequence;
257 ctx_first.task_id = 1;
259 OrderingArgs ctx_second;
260 ctx_second.mtx = &mtx;
261 ctx_second.sequence = &sequence;
262 ctx_second.task_id = 2;
264 auto first_task = kstd::make_unique<TaskControlBlock>(
265 "OrderFirst", 10, ordering_first,
reinterpret_cast<void*
>(&ctx_first));
266 auto second_task = kstd::make_unique<TaskControlBlock>(
267 "OrderSecond", 10, ordering_second,
reinterpret_cast<void*
>(&ctx_second));
269 TaskManagerSingleton::instance().AddTask(std::move(first_task));
270 TaskManagerSingleton::instance().AddTask(std::move(second_task));
273 while (timeout > 0 && sequence.load() != 2) {
278 if (sequence.load() != 2) {
279 klog::Err(
"test_mutex_ordering: FAIL — final sequence={}, expected 2",
287 klog::Err(
"Mutex Ordering Test: FAILED");
298 klog::Info(
"=== Mutex System Test Suite ===");
300 g_tests_completed = 0;
303 auto& task_mgr = TaskManagerSingleton::instance();
305 auto test1 = kstd::make_unique<TaskControlBlock>(
306 "TestMutexBasic", 10, test_mutex_basic_lock_unlock,
nullptr);
307 task_mgr.AddTask(std::move(test1));
309 auto test2 = kstd::make_unique<TaskControlBlock>(
"TestMutexTryLock", 10,
310 test_mutex_trylock,
nullptr);
311 task_mgr.AddTask(std::move(test2));
313 auto test3 = kstd::make_unique<TaskControlBlock>(
314 "TestMutexContention", 10, test_mutex_contention,
nullptr);
315 task_mgr.AddTask(std::move(test3));
317 auto test4 = kstd::make_unique<TaskControlBlock>(
318 "TestMutexOrdering", 10, test_mutex_ordering,
nullptr);
319 task_mgr.AddTask(std::move(test4));
321 constexpr int kExpectedTests = 4;
323 while (timeout > 0) {
325 if (g_tests_completed >= kExpectedTests) {
331 EXPECT_EQ(g_tests_completed.load(), kExpectedTests,
332 "All mutex tests should complete");
333 EXPECT_EQ(g_tests_failed.load(), 0,
"No mutex tests should fail");
335 klog::Info(
"Mutex System Test Suite: COMPLETED");
auto Lock() -> Expected< void >
获取锁(阻塞)
auto mutex_test() -> bool
auto Err(etl::format_string< Args... > fmt, Args &&... args) -> void
以 ERROR 级别记录日志
auto Info(etl::format_string< Args... > fmt, Args &&... args) -> void
以 INFO 级别记录日志
auto sys_sleep(uint64_t ms) -> int
休眠指定毫秒数
auto sys_exit(int code) -> int
退出当前进程或线程
#define EXPECT_EQ(val1, val2, msg)