diff --git a/examples/utest/testcases/kernel/mutex_tc.c b/examples/utest/testcases/kernel/mutex_tc.c index d5ec9095e4..00fbec68fd 100644 --- a/examples/utest/testcases/kernel/mutex_tc.c +++ b/examples/utest/testcases/kernel/mutex_tc.c @@ -26,6 +26,8 @@ static struct rt_mutex static_mutex; static rt_mutex_t dynamic_mutex; #endif /* RT_USING_HEAP */ +static volatile int _sync_flag; + /* init test */ static void test_static_mutex_init(void) { @@ -72,11 +74,15 @@ static void static_mutex_take_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } + static void test_static_mutex_take(void) { rt_err_t result; + _sync_flag = 0; + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); if (RT_EOK != result) { @@ -104,8 +110,10 @@ static void test_static_mutex_take(void) /* startup thread take second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_detach(&static_mutex); if (RT_EOK != result) @@ -128,11 +136,14 @@ static void static_mutex_release_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } static void test_static_mutex_release(void) { rt_err_t result; + _sync_flag = 0; + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); if (RT_EOK != result) { @@ -140,6 +151,9 @@ static void test_static_mutex_release(void) return; } + result = rt_mutex_release(&static_mutex); + uassert_true(result < 0); + /* take mutex */ result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); if (RT_EOK != result) @@ -165,8 +179,10 @@ static void test_static_mutex_release(void) /* startup thread and take mutex second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_detach(&static_mutex); if (RT_EOK != result) @@ -188,11 +204,14 @@ static void static_mutex_trytake_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } static void test_static_mutex_trytake(void) { rt_err_t result; + _sync_flag = 0; + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); if (RT_EOK != result) { @@ -220,8 +239,10 @@ static void test_static_mutex_trytake(void) /* startup thread and trytake mutex second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_detach(&static_mutex); if (RT_EOK != result) @@ -250,6 +271,7 @@ static void static_thread1_entry(void *param) { uassert_true(RT_TRUE); } + _sync_flag++; } static void static_thread2_entry(void *param) @@ -265,6 +287,7 @@ static void static_thread2_entry(void *param) { rt_mutex_release(mutex); } + _sync_flag++; } static void static_thread3_entry(void *param) { @@ -282,6 +305,7 @@ static void static_thread3_entry(void *param) while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2)); rt_mutex_release(mutex); + _sync_flag++; } static void test_static_pri_reverse(void) @@ -291,6 +315,8 @@ static void test_static_pri_reverse(void) tid2 = RT_NULL; tid3 = RT_NULL; + _sync_flag = 0; + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); if (RT_EOK != result) { @@ -328,7 +354,10 @@ static void test_static_pri_reverse(void) if (tid3 != RT_NULL) rt_thread_startup(tid3); - rt_thread_mdelay(1000); + while (_sync_flag != 3) + { + rt_thread_mdelay(10); + } result = rt_mutex_detach(&static_mutex); if (RT_EOK != result) @@ -385,11 +414,15 @@ static void dynamic_mutex_take_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } + static void test_dynamic_mutex_take(void) { rt_err_t result; + _sync_flag = 0; + dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); if (RT_NULL == dynamic_mutex) { @@ -417,8 +450,10 @@ static void test_dynamic_mutex_take(void) /* startup thread take second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_delete(dynamic_mutex); if (RT_EOK != result) @@ -441,11 +476,13 @@ static void dynamic_mutex_release_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } static void test_dynamic_mutex_release(void) { rt_err_t result; + _sync_flag = 0; dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); if (RT_NULL == dynamic_mutex) { @@ -453,6 +490,9 @@ static void test_dynamic_mutex_release(void) return; } + result = rt_mutex_release(dynamic_mutex); + uassert_true(result < 0); + /* take mutex */ result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER); if (RT_EOK != result) @@ -478,8 +518,10 @@ static void test_dynamic_mutex_release(void) /* startup thread and take mutex second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_delete(dynamic_mutex); if (RT_EOK != result) @@ -501,11 +543,13 @@ static void dynamic_mutex_trytake_entry(void *param) { uassert_true(RT_FALSE); } + _sync_flag++; } static void test_dynamic_mutex_trytake(void) { rt_err_t result; + _sync_flag = 0; dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); if (RT_NULL == dynamic_mutex) { @@ -533,8 +577,10 @@ static void test_dynamic_mutex_trytake(void) /* startup thread and trytake mutex second */ rt_thread_startup(tid); - /* let system schedule */ - rt_thread_mdelay(5); + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } result = rt_mutex_delete(dynamic_mutex); if (RT_EOK != result) @@ -559,6 +605,7 @@ static void dynamic_thread1_entry(void *param) { uassert_true(RT_TRUE); } + _sync_flag++; } static void dynamic_thread2_entry(void *param) @@ -574,6 +621,7 @@ static void dynamic_thread2_entry(void *param) { rt_mutex_release(mutex); } + _sync_flag++; } static void dynamic_thread3_entry(void *param) { @@ -591,6 +639,7 @@ static void dynamic_thread3_entry(void *param) while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2)); rt_mutex_release(mutex); + _sync_flag++; } static void test_dynamic_pri_reverse(void) @@ -600,6 +649,7 @@ static void test_dynamic_pri_reverse(void) tid2 = RT_NULL; tid3 = RT_NULL; + _sync_flag = 0; dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO); if (RT_NULL == dynamic_mutex) { @@ -637,7 +687,10 @@ static void test_dynamic_pri_reverse(void) if (tid3 != RT_NULL) rt_thread_startup(tid3); - rt_thread_mdelay(1000); + while (_sync_flag != 3) + { + rt_thread_mdelay(10); + } result = rt_mutex_delete(dynamic_mutex); if (RT_EOK != result) @@ -646,6 +699,66 @@ static void test_dynamic_pri_reverse(void) uassert_true(RT_TRUE); } +static void recursive_lock_test_entry(void *param) +{ + rt_err_t result; + rt_mutex_t mutex = (rt_mutex_t)param; + + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + uassert_true(result == RT_EOK); + uassert_true(_sync_flag == 0); + result = rt_mutex_take(mutex, RT_WAITING_FOREVER); + uassert_true(result == RT_EOK); + _sync_flag++; +} + +static void test_recurse_lock(void) +{ + rt_err_t result; + + _sync_flag = 0; + result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO); + uassert_true(result == RT_EOK); + + /* take mutex and not release */ + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + uassert_true(result == RT_EOK); + + /* take mutex twice */ + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + uassert_true(result == RT_EOK); + + rt_thread_t tid = rt_thread_create("mutex_th", + recursive_lock_test_entry, + &static_mutex, + THREAD_STACKSIZE, + 10, + 10); + _sync_flag = -1; + + if (tid != RT_NULL) + rt_thread_startup(tid); + + result = rt_mutex_release(&static_mutex); + uassert_true(result == RT_EOK); + + _sync_flag = 0; + + result = rt_mutex_release(&static_mutex); + uassert_true(result == RT_EOK); + + while (_sync_flag != 1) + { + rt_thread_mdelay(10); + } + + result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER); + uassert_true(result == RT_EOK); + + result = rt_mutex_detach(&static_mutex); + uassert_true(result == RT_EOK); +} + static rt_err_t utest_tc_init(void) { #ifdef RT_USING_HEAP @@ -678,6 +791,7 @@ static void testcase(void) UTEST_UNIT_RUN(test_dynamic_mutex_trytake); UTEST_UNIT_RUN(test_dynamic_pri_reverse); #endif + UTEST_UNIT_RUN(test_recurse_lock); } UTEST_TC_EXPORT(testcase, "testcases.kernel.mutex_tc", utest_tc_init, utest_tc_cleanup, 1000);