1 #include "ktest_utils.h"
2 #include <common/mutex.h>
3 #include <common/time.h>
4 #include <common/sys/wait.h>
5 #include <process/process.h>
6 
7 static mutex_t mtx;
8 
9 /**
10  * @brief 测试是否能够加锁
11  *
12  * @param arg0
13  * @param arg1
14  * @return long
15  */
ktest_mutex_case0(uint64_t arg0,uint64_t arg1)16 static long ktest_mutex_case0(uint64_t arg0, uint64_t arg1)
17 {
18     assert(mutex_is_locked(&mtx) == 0);
19     mutex_lock(&mtx);
20     assert(mutex_is_locked(&mtx) == 1);
21     mutex_unlock(&mtx);
22     assert(mutex_is_locked(&mtx) == 0);
23     assert(mutex_trylock(&mtx) == 1);
24     mutex_unlock(&mtx);
25     assert(mutex_is_locked(&mtx) == 0);
26 }
27 
28 /**
29  * @brief 测试用例1的辅助线程
30  *
31  * @param arg
32  * @return long
33  */
ktest_mutex_case1_pid1(void * arg)34 static int ktest_mutex_case1_pid1(void* arg)
35 {
36     kTEST("ktest_mutex_case1_subproc start.");
37     assert(mutex_is_locked(&mtx) == 1);
38     mutex_lock(&mtx);
39     assert(atomic_read(&mtx.count) == 0);
40     assert(list_empty(&mtx.wait_list));
41 
42     mutex_unlock(&mtx);
43     kTEST("ktest_mutex_case1_subproc exit.");
44     return 0;
45 }
46 
ktest_mutex_case1(uint64_t arg0,uint64_t arg1)47 static long ktest_mutex_case1(uint64_t arg0, uint64_t arg1)
48 {
49     if (!assert(mutex_is_locked(&mtx) == 0))
50         goto failed;
51 
52     // 加锁
53     mutex_lock(&mtx);
54     // 启动另一个线程
55     pid_t pid = kernel_thread(ktest_mutex_case1_pid1, 0, 0);
56     // 等待100ms
57     usleep(100000);
58     while (list_empty(&mtx.wait_list))
59         ;
60 
61     // 当子线程加锁后,计数应当为0
62     assert(atomic_read(&mtx.count) == 0);
63     struct mutex_waiter_t *wt = container_of(list_next(&mtx.wait_list), struct mutex_waiter_t, list);
64     assert(wt->pcb->pid == pid);
65 
66     mutex_unlock(&mtx);
67 
68     int stat = 1;
69     waitpid(pid, &stat, 0);
70     assert(stat == 0);
71     return 0;
72 failed:;
73     kTEST("mutex test case1 failed.");
74     return -1;
75 }
76 
77 static ktest_case_table kt_mutex_func_table[] = {
78     ktest_mutex_case0,
79     ktest_mutex_case1,
80 };
ktest_test_mutex(void * arg)81 int ktest_test_mutex(void* arg)
82 {
83     kTEST("Testing mutex...");
84     mutex_init(&mtx);
85 
86     for (int i = 0; i < sizeof(kt_mutex_func_table) / sizeof(ktest_case_table); ++i)
87     {
88         kTEST("Testing case %d", i);
89         kt_mutex_func_table[i](i, 0);
90     }
91     kTEST("mutex Test done.");
92     return 0;
93 }