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_os.h>
10 
11 #define STACKSZ CONFIG_CMSIS_THREAD_MAX_STACK_SIZE
12 
13 static osPriority osPriorityDeadline = 10;
14 
15 /* This is used to check the thread yield functionality between 2 threads */
16 static int thread_yield_check;
17 
18 /* This is used to indicate the completion of processing for thread3 */
19 static int thread3_state;
20 
thread1(void const * argument)21 void thread1(void const *argument)
22 {
23 	osStatus status;
24 	osThreadId id = osThreadGetId();
25 
26 	zassert_true(id != NULL, "Failed getting Thread ID");
27 
28 	/* This thread starts off at a high priority (same as thread2) */
29 	thread_yield_check++;
30 	zassert_equal(thread_yield_check, 1);
31 
32 	/* Yield to thread2 which is of same priority */
33 	status = osThreadYield();
34 	zassert_true(status == osOK, "Error doing thread yield");
35 
36 	/* thread_yield_check should now be 2 as it was incremented
37 	 * in thread2.
38 	 */
39 	zassert_equal(thread_yield_check, 2);
40 }
41 
thread2(void const * argument)42 void thread2(void const *argument)
43 {
44 	/* By now thread1 would have set thread_yield_check to 1 and would
45 	 * have yielded the CPU. Incrementing it over here would essentially
46 	 * confirm that the yield was indeed executed.
47 	 */
48 	thread_yield_check++;
49 
50 	/* Yield back to thread1 which is of same priority */
51 	osThreadYield();
52 }
53 
thread3(void const * argument)54 void thread3(void const *argument)
55 {
56 	osStatus status;
57 	osPriority rv;
58 	osThreadId id = osThreadGetId();
59 	osPriority prio = osThreadGetPriority(id);
60 
61 	/* Lower the priority of the current thread */
62 	osThreadSetPriority(id, osPriorityBelowNormal);
63 	rv = osThreadGetPriority(id);
64 	zassert_equal(rv, osPriorityBelowNormal,
65 			"Expected priority to be changed to %d, not %d",
66 			(int)osPriorityBelowNormal, (int)rv);
67 
68 	/* Increase the priority of the current thread */
69 	osThreadSetPriority(id, osPriorityAboveNormal);
70 	rv = osThreadGetPriority(id);
71 	zassert_equal(rv, osPriorityAboveNormal,
72 			"Expected priority to be changed to %d, not %d",
73 			(int)osPriorityAboveNormal, (int)rv);
74 
75 	/* Restore the priority of the current thread */
76 	osThreadSetPriority(id, prio);
77 	rv = osThreadGetPriority(id);
78 	zassert_equal(rv, prio,
79 			"Expected priority to be changed to %d, not %d",
80 			(int)prio, (int)rv);
81 
82 	/* Try to set unsupported priority and assert failure */
83 	status = osThreadSetPriority(id, osPriorityDeadline);
84 	zassert_true(status == osErrorValue,
85 			"Something's wrong with osThreadSetPriority!");
86 
87 	/* Indication that thread3 is done with its processing */
88 	thread3_state = 1;
89 
90 	/* Keep looping till it gets killed */
91 	do {
92 		osDelay(100);
93 	} while (1);
94 }
95 
96 osThreadDef(thread1, osPriorityHigh, 1, STACKSZ);
97 osThreadDef(thread2, osPriorityHigh, 1, STACKSZ);
98 osThreadDef(thread3, osPriorityNormal, 1, STACKSZ);
99 
ZTEST(thread_apis,test_thread_prio)100 ZTEST(thread_apis, test_thread_prio)
101 {
102 	osStatus status;
103 	osThreadId id3;
104 
105 	id3 = osThreadCreate(osThread(thread3), NULL);
106 	zassert_true(id3 != NULL, "Failed creating thread3");
107 
108 	/* Keep delaying 10 milliseconds to ensure thread3 is done with
109 	 * its execution. It loops at the end and is terminated here.
110 	 */
111 	do {
112 		osDelay(10);
113 	} while (thread3_state == 0);
114 
115 	status = osThreadTerminate(id3);
116 	zassert_true(status == osOK, "Error terminating thread3");
117 
118 	/* Try to set priority to inactive thread and assert failure */
119 	status = osThreadSetPriority(id3, osPriorityNormal);
120 	zassert_true(status == osErrorResource,
121 			"Something's wrong with osThreadSetPriority!");
122 
123 	/* Try to terminate inactive thread and assert failure */
124 	status = osThreadTerminate(id3);
125 	zassert_true(status == osErrorResource,
126 			"Something's wrong with osThreadTerminate!");
127 
128 	thread3_state = 0;
129 }
130 
ZTEST(thread_apis,test_thread_apis)131 ZTEST(thread_apis, test_thread_apis)
132 {
133 	osThreadId id1;
134 	osThreadId id2;
135 
136 	id1 = osThreadCreate(osThread(thread1), NULL);
137 	zassert_true(id1 != NULL, "Failed creating thread1");
138 
139 	id2 = osThreadCreate(osThread(thread2), NULL);
140 	zassert_true(id2 != NULL, "Failed creating thread2");
141 
142 	do {
143 		osDelay(100);
144 	} while (thread_yield_check != 2);
145 }
146 ZTEST_SUITE(thread_apis, NULL, NULL, NULL, NULL, NULL);
147