1 /*
2 * Copyright (c) 2017 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9 #include <cmsis_os.h>
10
11 #define TIMEOUT 500
12
13 osMutexDef(Mutex_1);
14 osMutexDef(Mutex_2);
15 osMutexDef(Mutex_multi);
16
17 int max_mtx_cnt = CONFIG_CMSIS_MUTEX_MAX_COUNT;
18
cleanup_max_mutex(osMutexId * mutex_ids)19 void cleanup_max_mutex(osMutexId *mutex_ids)
20 {
21 int mutex_count = 0;
22 osStatus status;
23
24 for (mutex_count = 0; mutex_count < max_mtx_cnt; mutex_count++) {
25 status = osMutexDelete(mutex_ids[mutex_count]);
26 zassert_true(status == osOK, "Mutex delete fail");
27 }
28 }
29
test_max_mutex(void)30 void test_max_mutex(void)
31 {
32 osMutexId mutex_ids[CONFIG_CMSIS_MUTEX_MAX_COUNT + 1];
33 int mtx_cnt = 0;
34
35 /* Try mutex creation for more than maximum count */
36 for (mtx_cnt = 0; mtx_cnt < max_mtx_cnt + 1; mtx_cnt++) {
37 mutex_ids[mtx_cnt] = osMutexCreate(osMutex(Mutex_multi));
38 if (mtx_cnt == max_mtx_cnt) {
39 zassert_true(mutex_ids[mtx_cnt] == NULL,
40 "Mutex creation pass unexpectedly after max count");
41 cleanup_max_mutex(mutex_ids);
42 } else {
43 zassert_true(mutex_ids[mtx_cnt] != NULL,
44 "Multiple mutex creation failed before max count");
45 }
46 }
47 }
48
ZTEST(cmsis_mutex,test_mutex)49 ZTEST(cmsis_mutex, test_mutex)
50 {
51 osMutexId mutex_id = 0;
52 osStatus status;
53
54 /* Try deleting invalid mutex object */
55 status = osMutexDelete(mutex_id);
56 zassert_true(status == osErrorParameter,
57 "Invalid Mutex deleted unexpectedly!");
58
59 mutex_id = osMutexCreate(osMutex(Mutex_1));
60 zassert_true(mutex_id != NULL, "Mutex1 creation failed");
61
62 /* Try to release mutex without obtaining it */
63 status = osMutexRelease(mutex_id);
64 zassert_true(status == osErrorResource, "Mutex released unexpectedly!");
65
66 status = osMutexWait(mutex_id, 0);
67 zassert_true(status == osOK, "Mutex wait failure");
68
69 /* Try to acquire an already acquired mutex */
70 status = osMutexWait(mutex_id, 0);
71 zassert_true(status == osOK, "Mutex wait failure");
72
73 status = osMutexRelease(mutex_id);
74 zassert_true(status == osOK, "Mutex release failure");
75
76 /* Release mutex again as it was acquired twice */
77 status = osMutexRelease(mutex_id);
78 zassert_true(status == osOK, "Mutex release failure");
79
80 /* Try to release mutex that was already released */
81 status = osMutexRelease(mutex_id);
82 zassert_true(status == osErrorResource, "Mutex released unexpectedly!");
83
84 status = osMutexDelete(mutex_id);
85 zassert_true(status == osOK, "Mutex delete failure");
86
87 /* Try mutex creation for more than maximum allowed count */
88 test_max_mutex();
89 }
90
tThread_entry_lock_timeout(void const * arg)91 void tThread_entry_lock_timeout(void const *arg)
92 {
93 osStatus status;
94
95 /* Mutex cannot be acquired here as it is still held by the
96 * other thread. Try with and without timeout.
97 */
98 status = osMutexWait((osMutexId)arg, 0);
99 zassert_true(status == osErrorResource);
100
101 status = osMutexWait((osMutexId)arg, TIMEOUT - 100);
102 zassert_true(status == osErrorTimeoutResource);
103
104 /* At this point, mutex is held by the other thread.
105 * Trying to release it here should fail.
106 */
107 status = osMutexRelease((osMutexId)arg);
108 zassert_true(status == osErrorResource, "Mutex unexpectedly released");
109
110 /* This delay ensures that the mutex gets released by the other
111 * thread in the meantime
112 */
113 osDelay(TIMEOUT - 100);
114
115 /* Now that the mutex is free, it should be possible to acquire
116 * and release it.
117 */
118 status = osMutexWait((osMutexId)arg, TIMEOUT);
119 zassert_true(status == osOK);
120 osMutexRelease((osMutexId)arg);
121 }
122
123 osThreadDef(tThread_entry_lock_timeout, osPriorityNormal, 1, 0);
124
ZTEST(cmsis_mutex,test_mutex_lock_timeout)125 ZTEST(cmsis_mutex, test_mutex_lock_timeout)
126 {
127 osThreadId id;
128 osMutexId mutex_id;
129 osStatus status;
130
131 mutex_id = osMutexCreate(osMutex(Mutex_2));
132 zassert_true(mutex_id != NULL, "Mutex2 creation failed");
133
134 id = osThreadCreate(osThread(tThread_entry_lock_timeout), mutex_id);
135 zassert_true(id != NULL, "Thread creation failed");
136
137 status = osMutexWait(mutex_id, osWaitForever);
138 zassert_true(status == osOK, "Mutex wait failure");
139
140 /* wait for spawn thread to take action */
141 osDelay(TIMEOUT);
142
143 /* Release the mutex to be used by the other thread */
144 osMutexRelease(mutex_id);
145 osDelay(TIMEOUT);
146
147 osMutexDelete(mutex_id);
148 }
149 ZTEST_SUITE(cmsis_mutex, NULL, NULL, NULL, NULL, NULL);
150