summaryrefslogtreecommitdiff
path: root/examples/utest
diff options
context:
space:
mode:
Diffstat (limited to 'examples/utest')
-rw-r--r--examples/utest/configs/kernel/ipc.conf2
-rw-r--r--examples/utest/testcases/kernel/Kconfig4
-rw-r--r--examples/utest/testcases/kernel/SConscript3
-rw-r--r--examples/utest/testcases/kernel/mutex_tc.c676
4 files changed, 685 insertions, 0 deletions
diff --git a/examples/utest/configs/kernel/ipc.conf b/examples/utest/configs/kernel/ipc.conf
index f8e687e633..f961e082e1 100644
--- a/examples/utest/configs/kernel/ipc.conf
+++ b/examples/utest/configs/kernel/ipc.conf
@@ -2,8 +2,10 @@ CONFIG_UTEST_SEMAPHORE_TC=y
CONFIG_UTEST_EVENT_TC=y
CONFIG_UTEST_MESSAGEQUEUE_TC=y
CONFIG_UTEST_SIGNAL_TC=y
+CONFIG_UTEST_MUTEX_TC=y
# dependencies
CONFIG_RT_USING_SEMAPHORE=y
CONFIG_RT_USING_EVENT=y
CONFIG_RT_USING_MESSAGEQUEUE=y
CONFIG_RT_USING_SIGNALS=y
+CONFIG_RT_USING_MUTEX=y \ No newline at end of file
diff --git a/examples/utest/testcases/kernel/Kconfig b/examples/utest/testcases/kernel/Kconfig
index f4673aebb9..fd4e1fecb9 100644
--- a/examples/utest/testcases/kernel/Kconfig
+++ b/examples/utest/testcases/kernel/Kconfig
@@ -31,4 +31,8 @@ config UTEST_SIGNAL_TC
bool "signal test"
default n
+config UTEST_MUTEX_TC
+ bool "mutex test"
+ default n
+
endmenu
diff --git a/examples/utest/testcases/kernel/SConscript b/examples/utest/testcases/kernel/SConscript
index ca34db6fed..4bf0a2e60b 100644
--- a/examples/utest/testcases/kernel/SConscript
+++ b/examples/utest/testcases/kernel/SConscript
@@ -26,6 +26,9 @@ if GetDepend(['UTEST_MESSAGEQUEUE_TC']):
if GetDepend(['UTEST_SIGNAL_TC']):
src += ['signal_tc.c']
+if GetDepend(['UTEST_MUTEX_TC']):
+ src += ['mutex_tc.c']
+
CPPPATH = [cwd]
group = DefineGroup('utestcases', src, depend = [], CPPPATH = CPPPATH)
diff --git a/examples/utest/testcases/kernel/mutex_tc.c b/examples/utest/testcases/kernel/mutex_tc.c
new file mode 100644
index 0000000000..0ec443318a
--- /dev/null
+++ b/examples/utest/testcases/kernel/mutex_tc.c
@@ -0,0 +1,676 @@
+/*
+ * Copyright (c) 2006-2019, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-09.01 luckyzjq the first version
+ */
+
+#include <rtthread.h>
+#include <stdlib.h>
+#include "utest.h"
+
+static struct rt_mutex static_mutex;
+
+#ifdef RT_USING_HEAP
+static rt_mutex_t dynamic_mutex;
+#endif /* RT_USING_HEAP */
+
+/* init test */
+static void test_static_mutex_init(void)
+{
+ rt_err_t result = -RT_ERROR;
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_FIFO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ uassert_true(RT_TRUE);
+}
+
+/* static take test */
+static void static_mutex_take_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ int rand_num = rand() % 0x1000;
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, rand_num);
+ if (RT_EOK == result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_static_mutex_take(void)
+{
+ rt_err_t result;
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex and not release */
+ result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ static_mutex_take_entry,
+ &static_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread take second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* static release test */
+static void static_mutex_release_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ int rand_num = rand() % 0x1000;
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, rand_num);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_static_mutex_release(void)
+{
+ rt_err_t result;
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex */
+ result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ /* release mutex */
+ result = rt_mutex_release(&static_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ static_mutex_release_entry,
+ &static_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread adn take mutex second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* static trytake test */
+static void static_mutex_trytake_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_trytake(mutex);
+ if (RT_EOK == result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_static_mutex_trytake(void)
+{
+ rt_err_t result;
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex and not release */
+ result = rt_mutex_take(&static_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ static_mutex_trytake_entry,
+ &static_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread and trytake mutex second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+static rt_thread_t tid1 = RT_NULL;
+static rt_thread_t tid2 = RT_NULL;
+static rt_thread_t tid3 = RT_NULL;
+
+/* static mutex priority reverse test */
+static void static_thread1_entry(void *param)
+{
+ /* let system schedule */
+ rt_thread_mdelay(100);
+
+ /* thread3 hode mutex thread2 take mutex */
+ /* check thread2 and thread3 priority */
+ if (tid2->current_priority != tid3->current_priority)
+ {
+ uassert_true(RT_FALSE);
+ }
+ else
+ {
+ uassert_true(RT_TRUE);
+ }
+}
+
+static void static_thread2_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex = (rt_mutex_t)param;
+
+ /* let system schedule */
+ rt_thread_mdelay(50);
+
+ result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ if (result == RT_EOK)
+ {
+ rt_mutex_release(mutex);
+ }
+}
+static void static_thread3_entry(void *param)
+{
+ rt_tick_t tick;
+ rt_err_t result;
+ rt_mutex_t mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ if (result != RT_EOK)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ tick = rt_tick_get();
+ while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
+
+ rt_mutex_release(mutex);
+}
+
+static void test_static_pri_reverse(void)
+{
+ rt_err_t result;
+ tid1 = RT_NULL;
+ tid2 = RT_NULL;
+ tid3 = RT_NULL;
+
+ result = rt_mutex_init(&static_mutex, "static_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* 创建线程 1 */
+ tid1 = rt_thread_create("thread1",
+ static_thread1_entry,
+ &static_mutex,
+ 1024,
+ 10 - 1,
+ 10);
+ if (tid1 != RT_NULL)
+ rt_thread_startup(tid1);
+
+ /* 创建线程 2 */
+ tid2 = rt_thread_create("thread2",
+ static_thread2_entry,
+ &static_mutex,
+ 1024,
+ 10,
+ 10);
+ if (tid2 != RT_NULL)
+ rt_thread_startup(tid2);
+
+ /* 创建线程 3 */
+ tid3 = rt_thread_create("thread3",
+ static_thread3_entry,
+ &static_mutex,
+ 1024,
+ 10 + 1,
+ 10);
+ if (tid3 != RT_NULL)
+ rt_thread_startup(tid3);
+
+ rt_thread_mdelay(1000);
+
+ result = rt_mutex_detach(&static_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* create test */
+static void test_dynamic_mutex_create(void)
+{
+ rt_err_t result = -RT_ERROR;
+
+ /* PRIO mode */
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_NULL == result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ /* FIFO mode */
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_FIFO);
+ if (RT_NULL == dynamic_mutex)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ uassert_true(RT_TRUE);
+}
+
+/* dynamic take test */
+static void dynamic_mutex_take_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ int rand_num = rand() % 0x1000;
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, rand_num);
+ if (RT_EOK == result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_dynamic_mutex_take(void)
+{
+ rt_err_t result;
+
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_NULL == dynamic_mutex)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex and not release */
+ result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ dynamic_mutex_take_entry,
+ dynamic_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread take second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* dynamic release test */
+static void dynamic_mutex_release_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ int rand_num = rand() % 0x1000;
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, rand_num);
+ if (RT_EOK != result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_dynamic_mutex_release(void)
+{
+ rt_err_t result;
+
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_NULL == dynamic_mutex)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex */
+ result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ /* release mutex */
+ result = rt_mutex_release(dynamic_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ dynamic_mutex_release_entry,
+ dynamic_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread adn take mutex second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* dynamic trytake test */
+static void dynamic_mutex_trytake_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex;
+
+ mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_trytake(mutex);
+ if (RT_EOK == result)
+ {
+ uassert_true(RT_FALSE);
+ }
+}
+static void test_dynamic_mutex_trytake(void)
+{
+ rt_err_t result;
+
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_NULL == dynamic_mutex)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* take mutex and not release */
+ result = rt_mutex_take(dynamic_mutex, RT_WAITING_FOREVER);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ rt_thread_t tid = rt_thread_create("mutex_th",
+ dynamic_mutex_trytake_entry,
+ dynamic_mutex,
+ 2048,
+ 10,
+ 10);
+ if (RT_NULL == tid)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* startup thread and trytake mutex second */
+ rt_thread_startup(tid);
+
+ /* let system schedule */
+ rt_thread_mdelay(5);
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+/* dynamic mutex priority reverse test */
+static void dynamic_thread1_entry(void *param)
+{
+ /* let system schedule */
+ rt_thread_mdelay(100);
+
+ /* thread3 hode mutex thread2 take mutex */
+ /* check thread2 and thread3 priority */
+ if (tid2->current_priority != tid3->current_priority)
+ {
+ uassert_true(RT_FALSE);
+ }
+ else
+ {
+ uassert_true(RT_TRUE);
+ }
+}
+
+static void dynamic_thread2_entry(void *param)
+{
+ rt_err_t result;
+ rt_mutex_t mutex = (rt_mutex_t)param;
+
+ /* let system schedule */
+ rt_thread_mdelay(50);
+
+ result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ if (result == RT_EOK)
+ {
+ rt_mutex_release(mutex);
+ }
+}
+static void dynamic_thread3_entry(void *param)
+{
+ rt_tick_t tick;
+ rt_err_t result;
+ rt_mutex_t mutex = (rt_mutex_t)param;
+
+ result = rt_mutex_take(mutex, RT_WAITING_FOREVER);
+ if (result != RT_EOK)
+ {
+ uassert_true(RT_FALSE);
+ }
+
+ tick = rt_tick_get();
+ while (rt_tick_get() - tick < (RT_TICK_PER_SECOND / 2));
+
+ rt_mutex_release(mutex);
+}
+
+static void test_dynamic_pri_reverse(void)
+{
+ rt_err_t result;
+ tid1 = RT_NULL;
+ tid2 = RT_NULL;
+ tid3 = RT_NULL;
+
+ dynamic_mutex = rt_mutex_create("dynamic_mutex", RT_IPC_FLAG_PRIO);
+ if (RT_NULL == dynamic_mutex)
+ {
+ uassert_true(RT_FALSE);
+ return;
+ }
+
+ /* 创建线程 1 */
+ tid1 = rt_thread_create("thread1",
+ dynamic_thread1_entry,
+ dynamic_mutex,
+ 1024,
+ 10 - 1,
+ 10);
+ if (tid1 != RT_NULL)
+ rt_thread_startup(tid1);
+
+ /* 创建线程 2 */
+ tid2 = rt_thread_create("thread2",
+ dynamic_thread2_entry,
+ dynamic_mutex,
+ 1024,
+ 10,
+ 10);
+ if (tid2 != RT_NULL)
+ rt_thread_startup(tid2);
+
+ /* 创建线程 3 */
+ tid3 = rt_thread_create("thread3",
+ dynamic_thread3_entry,
+ dynamic_mutex,
+ 1024,
+ 10 + 1,
+ 10);
+ if (tid3 != RT_NULL)
+ rt_thread_startup(tid3);
+
+ rt_thread_mdelay(1000);
+
+ result = rt_mutex_delete(dynamic_mutex);
+ if (RT_EOK != result)
+ uassert_true(RT_FALSE);
+
+ uassert_true(RT_TRUE);
+}
+
+static rt_err_t utest_tc_init(void)
+{
+#ifdef RT_USING_HEAP
+ dynamic_mutex = RT_NULL;
+#endif /* RT_USING_HEAP */
+
+ return RT_EOK;
+}
+
+static rt_err_t utest_tc_cleanup(void)
+{
+#ifdef RT_USING_HEAP
+ dynamic_mutex = RT_NULL;
+#endif /* RT_USING_HEAP */
+
+ return RT_EOK;
+}
+
+static void testcase(void)
+{
+ UTEST_UNIT_RUN(test_static_mutex_init);
+ UTEST_UNIT_RUN(test_static_mutex_take);
+ UTEST_UNIT_RUN(test_static_mutex_release);
+ UTEST_UNIT_RUN(test_static_mutex_trytake);
+ UTEST_UNIT_RUN(test_static_pri_reverse);
+#ifdef RT_USING_HEAP
+ UTEST_UNIT_RUN(test_dynamic_mutex_create);
+ UTEST_UNIT_RUN(test_dynamic_mutex_take);
+ UTEST_UNIT_RUN(test_dynamic_mutex_release);
+ UTEST_UNIT_RUN(test_dynamic_mutex_trytake);
+ UTEST_UNIT_RUN(test_dynamic_pri_reverse);
+#endif
+}
+UTEST_TC_EXPORT(testcase, "testcases.kernel.mutex_tc", utest_tc_init, utest_tc_cleanup, 1000);
+
+/********************* end of file ************************/