1 /*
2  * Copyright (c) 2018 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_os2.h>
10 
11 #define WAIT_TICKS      5
12 #define TIMEOUT_TICKS   (10 + WAIT_TICKS)
13 #define STACKSZ         CONFIG_CMSIS_V2_THREAD_MAX_STACK_SIZE
14 
thread_sema(void * arg)15 void thread_sema(void *arg)
16 {
17 	osStatus_t status;
18 
19 	/* Try taking semaphore immediately when it is not available */
20 	status = osSemaphoreAcquire((osSemaphoreId_t)arg, 0);
21 	zassert_true(status == osErrorResource,
22 		     "Semaphore acquired unexpectedly!");
23 
24 	/* Try taking semaphore after a TIMEOUT, but before release */
25 	status = osSemaphoreAcquire((osSemaphoreId_t)arg, WAIT_TICKS);
26 	zassert_true(status == osErrorTimeout,
27 		     "Semaphore acquired unexpectedly!");
28 
29 	/* This delay ensures that the semaphore gets released by the other
30 	 * thread in the meantime
31 	 */
32 	osDelay(TIMEOUT_TICKS);
33 
34 	/* Now that the semaphore is free, it should be possible to acquire
35 	 * and release it.
36 	 */
37 	status = osSemaphoreAcquire((osSemaphoreId_t)arg, 0);
38 	zassert_true(status == osOK, "Semaphore could not be acquired");
39 
40 	zassert_true(osSemaphoreRelease((osSemaphoreId_t)arg) == osOK,
41 		     "Semaphore release failure");
42 
43 	/* Try releasing when no semaphore is obtained */
44 	zassert_true(
45 		osSemaphoreRelease((osSemaphoreId_t)arg) == osErrorResource,
46 		"Semaphore released unexpectedly!");
47 }
48 
49 static K_THREAD_STACK_DEFINE(test_stack, STACKSZ);
50 static osThreadAttr_t thread_attr = {
51 	.name = "Sema_check",
52 	.attr_bits = osThreadDetached,
53 	.cb_mem = NULL,
54 	.cb_size = 0,
55 	.stack_mem = &test_stack,
56 	.stack_size = STACKSZ,
57 	.priority = osPriorityNormal,
58 	.tz_module = 0,
59 	.reserved = 0
60 };
61 
62 const osSemaphoreAttr_t sema_attr = {
63 	"mySemaphore",
64 	0,
65 	NULL,
66 	0U
67 };
68 
ZTEST(cmsis_semaphore,test_semaphore)69 ZTEST(cmsis_semaphore, test_semaphore)
70 {
71 	osThreadId_t id;
72 	osStatus_t status;
73 	osSemaphoreId_t semaphore_id;
74 	osSemaphoreId_t dummy_sem_id = NULL;
75 	const char *name;
76 
77 	semaphore_id = osSemaphoreNew(1, 1, &sema_attr);
78 	zassert_true(semaphore_id != NULL, "semaphore creation failed");
79 
80 	name = osSemaphoreGetName(semaphore_id);
81 	zassert_str_equal(sema_attr.name, name,
82 			  "Error getting Semaphore name");
83 
84 	id = osThreadNew(thread_sema, semaphore_id, &thread_attr);
85 	zassert_true(id != NULL, "Thread creation failed");
86 
87 	zassert_true(osSemaphoreGetCount(semaphore_id) == 1);
88 
89 	/* Acquire invalid semaphore */
90 	zassert_equal(osSemaphoreAcquire(dummy_sem_id, osWaitForever),
91 		      osErrorParameter, "Semaphore wait worked unexpectedly");
92 
93 	status = osSemaphoreAcquire(semaphore_id, osWaitForever);
94 	zassert_true(status == osOK, "Semaphore wait failure");
95 
96 	zassert_true(osSemaphoreGetCount(semaphore_id) == 0);
97 
98 	/* wait for spawn thread to take action */
99 	osDelay(TIMEOUT_TICKS);
100 
101 	/* Release invalid semaphore */
102 	zassert_equal(osSemaphoreRelease(dummy_sem_id), osErrorParameter,
103 		      "Semaphore release worked unexpectedly");
104 
105 	/* Release the semaphore to be used by the other thread */
106 	status = osSemaphoreRelease(semaphore_id);
107 	zassert_true(status == osOK, "Semaphore release failure");
108 
109 	osDelay(TIMEOUT_TICKS);
110 
111 	/* Delete invalid semaphore */
112 	zassert_equal(osSemaphoreDelete(dummy_sem_id), osErrorParameter,
113 		      "Semaphore delete worked unexpectedly");
114 
115 	status = osSemaphoreDelete(semaphore_id);
116 	zassert_true(status == osOK, "semaphore delete failure");
117 }
118 ZTEST_SUITE(cmsis_semaphore, NULL, NULL, NULL, NULL, NULL);
119