1 /*
2 * Copyright (c) 2006-2019, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2021-08-12 luckyzjq the first version
9 */
10
11 #include <rtthread.h>
12 #include <stdlib.h>
13 #include "utest.h"
14
15 static struct rt_semaphore static_semaphore;
16 #ifdef RT_USING_HEAP
17 static rt_sem_t dynamic_semaphore;
18 #endif /* RT_USING_HEAP */
19
test_static_semaphore_init(void)20 static void test_static_semaphore_init(void)
21 {
22 rt_err_t result;
23 int rand_num = rand() % 0x10000;
24
25 for (int i = 0; i < rand_num; i++)
26 {
27 result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO);
28 if (RT_EOK != result)
29 {
30 uassert_true(RT_FALSE);
31 break;
32 }
33 rt_sem_detach(&static_semaphore);
34
35 result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO);
36 if (RT_EOK != result)
37 {
38 uassert_true(RT_FALSE);
39 break;
40 }
41 rt_sem_detach(&static_semaphore);
42 }
43
44 uassert_true(RT_TRUE);
45 }
46
test_static_semaphore_detach(void)47 static void test_static_semaphore_detach(void)
48 {
49 rt_err_t result;
50 int rand_num = rand() % 0x10000;
51
52 for (int i = 0; i < rand_num; i++)
53 {
54 result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_PRIO);
55 if (RT_EOK != result)
56 {
57 break;
58 }
59
60 result = rt_sem_detach(&static_semaphore);
61 if (RT_EOK != result)
62 {
63 uassert_true(RT_FALSE);
64 break;
65 }
66
67 result = rt_sem_init(&static_semaphore, "static_sem", i, RT_IPC_FLAG_FIFO);
68 if (RT_EOK != result)
69 {
70 break;
71 }
72 result = rt_sem_detach(&static_semaphore);
73 if (RT_EOK != result)
74 {
75 uassert_true(RT_FALSE);
76 break;
77 }
78 }
79
80 uassert_true(RT_TRUE);
81 }
82
test_static_semaphore_take(void)83 static void test_static_semaphore_take(void)
84 {
85 rt_err_t result;
86 result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
87 if (RT_EOK == result)
88 {
89 /* first take */
90 result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER);
91 if (RT_EOK != result)
92 uassert_true(RT_FALSE);
93 /* second take */
94 result = rt_sem_take(&static_semaphore, 100);
95 if (-RT_ETIMEOUT != result)
96 uassert_true(RT_FALSE);
97 }
98 else
99 {
100 return;
101 }
102
103 rt_sem_detach(&static_semaphore);
104 uassert_true(RT_TRUE);
105
106 return;
107 }
108
test_static_semaphore_trytake(void)109 static void test_static_semaphore_trytake(void)
110 {
111 rt_err_t result;
112 result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
113 if (RT_EOK == result)
114 {
115 /* first take */
116 result = rt_sem_trytake(&static_semaphore);
117 if (RT_EOK != result)
118 uassert_true(RT_FALSE);
119 /* second take */
120 result = rt_sem_trytake(&static_semaphore);
121 if (-RT_ETIMEOUT != result)
122 uassert_true(RT_FALSE);
123 }
124 else
125 {
126 return;
127 }
128
129 rt_sem_detach(&static_semaphore);
130 uassert_true(RT_TRUE);
131
132 return;
133 }
134
test_static_semaphore_release(void)135 static void test_static_semaphore_release(void)
136 {
137 rt_err_t result;
138 result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO);
139 if (RT_EOK == result)
140 {
141 /* first take */
142 result = rt_sem_take(&static_semaphore, 100);
143 if (-RT_ETIMEOUT != result)
144 uassert_true(RT_FALSE);
145
146 /* release */
147 result = rt_sem_release(&static_semaphore);
148 if (RT_EOK != result)
149 uassert_true(RT_FALSE);
150
151 /* second take */
152 result = rt_sem_take(&static_semaphore, RT_WAITING_FOREVER);
153 if (RT_EOK != result)
154 uassert_true(RT_FALSE);
155 }
156 else
157 {
158 return;
159 }
160
161 rt_sem_detach(&static_semaphore);
162 uassert_true(RT_TRUE);
163
164 return;
165 }
166
test_static_semaphore_control(void)167 static void test_static_semaphore_control(void)
168 {
169 rt_err_t result;
170 int value = 0;
171
172 value = rand() % 100;
173 result = rt_sem_init(&static_semaphore, "static_sem", 1, RT_IPC_FLAG_PRIO);
174 if (RT_EOK == result)
175 {
176 result = rt_sem_control(&static_semaphore, RT_IPC_CMD_RESET, &value);
177 if (RT_EOK != result)
178 {
179 uassert_true(RT_FALSE);
180 }
181 }
182 else
183 {
184 return;
185 }
186
187 for (int i = 0; i < value; i++)
188 {
189 result = rt_sem_take(&static_semaphore, 10);
190 if (RT_EOK != result)
191 {
192 uassert_true(RT_FALSE);
193 }
194 }
195
196 rt_sem_detach(&static_semaphore);
197 uassert_true(RT_TRUE);
198 }
199
static_release_isr_hardware_callback(void * param)200 static void static_release_isr_hardware_callback(void *param)
201 {
202 rt_err_t result;
203
204 result = rt_sem_release(&static_semaphore);
205 if (RT_EOK != result)
206 {
207 uassert_true(RT_FALSE);
208 }
209 }
210
static_release_isr_software_callback(void * param)211 static void static_release_isr_software_callback(void *param)
212 {
213 rt_err_t result;
214
215 result = rt_sem_release(&static_semaphore);
216 if (RT_EOK != result)
217 {
218 uassert_true(RT_FALSE);
219 }
220 }
221
test_static_semaphore_release_isr(void)222 static void test_static_semaphore_release_isr(void)
223 {
224 rt_err_t result;
225 rt_timer_t hardware_timer;
226 rt_timer_t software_timer;
227
228 /* create timer */
229 hardware_timer = rt_timer_create("release_isr",
230 static_release_isr_hardware_callback,
231 RT_NULL,
232 100,
233 RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT);
234 software_timer = rt_timer_create("release_isr",
235 static_release_isr_software_callback,
236 RT_NULL,
237 100,
238 RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
239 /* start tiemr */
240 if (hardware_timer)
241 rt_timer_start(hardware_timer);
242 if (software_timer)
243 rt_timer_start(software_timer);
244
245 result = rt_sem_init(&static_semaphore, "static_sem", 0, RT_IPC_FLAG_PRIO);
246 if (RT_EOK == result)
247 {
248 for (int i = 0; i < 2; i++)
249 {
250 result = rt_sem_take(&static_semaphore, 1000);
251 if (RT_EOK != result)
252 {
253 uassert_true(RT_FALSE);
254 }
255 }
256 }
257 else
258 {
259 return;
260 }
261
262 rt_sem_detach(&static_semaphore);
263 rt_timer_delete(hardware_timer);
264 rt_timer_delete(software_timer);
265
266 uassert_true(RT_TRUE);
267 }
268
269 #ifdef RT_USING_HEAP
test_dynamic_semaphore_create(void)270 static void test_dynamic_semaphore_create(void)
271 {
272 int rand_num = rand() % 0x10000;
273
274 for (int i = 0; i < rand_num; i++)
275 {
276 dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO);
277 if (RT_NULL == dynamic_semaphore)
278 {
279 uassert_true(RT_FALSE);
280 break;
281 }
282 rt_sem_delete(dynamic_semaphore);
283
284 dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO);
285 if (RT_NULL == dynamic_semaphore)
286 {
287 uassert_true(RT_FALSE);
288 break;
289 }
290 rt_sem_delete(dynamic_semaphore);
291 }
292
293 uassert_true(RT_TRUE);
294 }
295
test_dynamic_semaphore_delete(void)296 static void test_dynamic_semaphore_delete(void)
297 {
298 rt_err_t result;
299 int rand_num = rand() % 0x10000;
300
301 for (int i = 0; i < rand_num; i++)
302 {
303 dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_PRIO);
304 if (RT_NULL == dynamic_semaphore)
305 {
306 break;
307 }
308
309 result = rt_sem_delete(dynamic_semaphore);
310 if (RT_EOK != result)
311 {
312 uassert_true(RT_FALSE);
313 break;
314 }
315
316 dynamic_semaphore = rt_sem_create("static_sem", i, RT_IPC_FLAG_FIFO);
317 if (RT_NULL == dynamic_semaphore)
318 {
319 break;
320 }
321 result = rt_sem_delete(dynamic_semaphore);
322 if (RT_EOK != result)
323 {
324 uassert_true(RT_FALSE);
325 break;
326 }
327 }
328
329 uassert_true(RT_TRUE);
330 }
331
test_dynamic_semaphore_take(void)332 static void test_dynamic_semaphore_take(void)
333 {
334 rt_err_t result;
335 dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
336 if (RT_NULL != dynamic_semaphore)
337 {
338 /* first take */
339 result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER);
340 if (RT_EOK != result)
341 uassert_true(RT_FALSE);
342 /* second take */
343 result = rt_sem_take(dynamic_semaphore, 100);
344 if (-RT_ETIMEOUT != result)
345 uassert_true(RT_FALSE);
346 }
347 else
348 {
349 return;
350 }
351
352 rt_sem_delete(dynamic_semaphore);
353 uassert_true(RT_TRUE);
354
355 return;
356 }
357
test_dynamic_semaphore_trytake(void)358 static void test_dynamic_semaphore_trytake(void)
359 {
360 rt_err_t result;
361 dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
362 if (RT_NULL != dynamic_semaphore)
363 {
364 /* first take */
365 result = rt_sem_trytake(dynamic_semaphore);
366 if (RT_EOK != result)
367 uassert_true(RT_FALSE);
368 /* second take */
369 result = rt_sem_trytake(dynamic_semaphore);
370 if (-RT_ETIMEOUT != result)
371 uassert_true(RT_FALSE);
372 }
373 else
374 {
375 return;
376 }
377
378 rt_sem_delete(dynamic_semaphore);
379 uassert_true(RT_TRUE);
380
381 return;
382 }
383
test_dynamic_semaphore_release(void)384 static void test_dynamic_semaphore_release(void)
385 {
386 rt_err_t result;
387 dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO);
388 if (RT_NULL != dynamic_semaphore)
389 {
390 /* first take */
391 result = rt_sem_take(dynamic_semaphore, 100);
392 if (-RT_ETIMEOUT != result)
393 uassert_true(RT_FALSE);
394
395 /* release */
396 result = rt_sem_release(dynamic_semaphore);
397 if (RT_EOK != result)
398 uassert_true(RT_FALSE);
399
400 /* second take */
401 result = rt_sem_take(dynamic_semaphore, RT_WAITING_FOREVER);
402 if (RT_EOK != result)
403 uassert_true(RT_FALSE);
404 }
405 else
406 {
407 return;
408 }
409
410 rt_sem_delete(dynamic_semaphore);
411 uassert_true(RT_TRUE);
412
413 return;
414 }
415
test_dynamic_semaphore_control(void)416 static void test_dynamic_semaphore_control(void)
417 {
418 rt_err_t result;
419 int value = 0;
420
421 value = rand() % 100;
422 dynamic_semaphore = rt_sem_create("static_sem", 1, RT_IPC_FLAG_PRIO);
423 if (RT_NULL != dynamic_semaphore)
424 {
425 result = rt_sem_control(dynamic_semaphore, RT_IPC_CMD_RESET, &value);
426 if (RT_EOK != result)
427 {
428 uassert_true(RT_FALSE);
429 }
430 }
431 else
432 {
433 return;
434 }
435
436 for (int i = 0; i < value; i++)
437 {
438 result = rt_sem_take(dynamic_semaphore, 10);
439 if (RT_EOK != result)
440 {
441 uassert_true(RT_FALSE);
442 }
443 }
444
445 rt_sem_delete(dynamic_semaphore);
446 uassert_true(RT_TRUE);
447 }
448
dynamic_release_isr_hardware_callback(void * param)449 static void dynamic_release_isr_hardware_callback(void *param)
450 {
451 rt_err_t result;
452
453 result = rt_sem_release(dynamic_semaphore);
454 if (RT_EOK != result)
455 {
456 uassert_true(RT_FALSE);
457 }
458 }
459
dynamic_release_isr_software_callback(void * param)460 static void dynamic_release_isr_software_callback(void *param)
461 {
462 rt_err_t result;
463
464 result = rt_sem_release(dynamic_semaphore);
465 if (RT_EOK != result)
466 {
467 uassert_true(RT_FALSE);
468 }
469 }
470
test_dynamic_semaphore_release_isr(void)471 static void test_dynamic_semaphore_release_isr(void)
472 {
473 rt_err_t result;
474 rt_timer_t hardware_timer;
475 rt_timer_t software_timer;
476
477 /* create timer */
478 hardware_timer = rt_timer_create("release_isr",
479 dynamic_release_isr_hardware_callback,
480 RT_NULL,
481 100,
482 RT_TIMER_FLAG_HARD_TIMER | RT_TIMER_FLAG_ONE_SHOT);
483 software_timer = rt_timer_create("release_isr",
484 dynamic_release_isr_software_callback,
485 RT_NULL,
486 100,
487 RT_TIMER_FLAG_SOFT_TIMER | RT_TIMER_FLAG_ONE_SHOT);
488 /* start tiemr */
489 if (hardware_timer)
490 rt_timer_start(hardware_timer);
491 if (software_timer)
492 rt_timer_start(software_timer);
493
494 dynamic_semaphore = rt_sem_create("static_sem", 0, RT_IPC_FLAG_PRIO);
495 if (RT_NULL != dynamic_semaphore)
496 {
497 for (int i = 0; i < 2; i++)
498 {
499 result = rt_sem_take(dynamic_semaphore, 1000);
500 if (RT_EOK != result)
501 {
502 uassert_true(RT_FALSE);
503 }
504 }
505 }
506 else
507 {
508 return;
509 }
510
511 rt_sem_delete(dynamic_semaphore);
512 rt_timer_delete(hardware_timer);
513 rt_timer_delete(software_timer);
514
515 uassert_true(RT_TRUE);
516 }
517
518 #endif /* RT_USING_HEAP */
519
utest_tc_init(void)520 static rt_err_t utest_tc_init(void)
521 {
522 #ifdef RT_USING_HEAP
523 dynamic_semaphore = RT_NULL;
524 #endif /* RT_USING_HEAP */
525
526 return RT_EOK;
527 }
528
utest_tc_cleanup(void)529 static rt_err_t utest_tc_cleanup(void)
530 {
531 #ifdef RT_USING_HEAP
532 dynamic_semaphore = RT_NULL;
533 #endif /* RT_USING_HEAP */
534
535 return RT_EOK;
536 }
537
testcase(void)538 static void testcase(void)
539 {
540 UTEST_UNIT_RUN(test_static_semaphore_init);
541 UTEST_UNIT_RUN(test_static_semaphore_take);
542 UTEST_UNIT_RUN(test_static_semaphore_release);
543 UTEST_UNIT_RUN(test_static_semaphore_detach);
544 UTEST_UNIT_RUN(test_static_semaphore_trytake);
545 UTEST_UNIT_RUN(test_static_semaphore_control);
546 UTEST_UNIT_RUN(test_static_semaphore_release_isr);
547
548 #ifdef RT_USING_HEAP
549 UTEST_UNIT_RUN(test_dynamic_semaphore_create);
550 UTEST_UNIT_RUN(test_dynamic_semaphore_take);
551 UTEST_UNIT_RUN(test_dynamic_semaphore_release);
552 UTEST_UNIT_RUN(test_dynamic_semaphore_delete);
553 UTEST_UNIT_RUN(test_dynamic_semaphore_trytake);
554 UTEST_UNIT_RUN(test_dynamic_semaphore_control);
555 UTEST_UNIT_RUN(test_dynamic_semaphore_release_isr);
556 #endif /* RT_USING_HEAP */
557 }
558 UTEST_TC_EXPORT(testcase, "testcases.kernel.semaphore_tc", utest_tc_init, utest_tc_cleanup, 1000);
559