1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8
9 #include <zephyr/irq_offload.h>
10
11 #include "tests_thread_apis.h"
12
13 static int thread2_data;
14
15 K_SEM_DEFINE(sem_thread2, 0, 1);
16 K_SEM_DEFINE(sem_thread1, 0, 1);
17
18 struct isr_arg {
19 k_tid_t thread;
20 int prio;
21 };
22
23 static struct isr_arg prio_args;
24
25 /**
26 * @brief Test ISR used to change a thread's priority
27 */
test_isr(const void * arg)28 static void test_isr(const void *arg)
29 {
30 const struct isr_arg *data = arg;
31
32 k_thread_priority_set(data->thread, data->prio);
33 }
34
35 /**
36 *
37 * @brief thread2 portion to test setting the priority
38 *
39 */
thread2_set_prio_test(void * p1,void * p2,void * p3)40 void thread2_set_prio_test(void *p1, void *p2, void *p3)
41 {
42 ARG_UNUSED(p1);
43 ARG_UNUSED(p2);
44 ARG_UNUSED(p3);
45
46 /* lower thread2 priority by 5 */
47 k_sem_take(&sem_thread2, K_FOREVER);
48 thread2_data = k_thread_priority_get(k_current_get());
49 k_sem_give(&sem_thread1);
50
51 /* raise thread2 priority by 10 */
52 k_sem_take(&sem_thread2, K_FOREVER);
53 thread2_data = k_thread_priority_get(k_current_get());
54 k_sem_give(&sem_thread1);
55
56 /* restore thread2 priority */
57 k_sem_take(&sem_thread2, K_FOREVER);
58 thread2_data = k_thread_priority_get(k_current_get());
59 k_sem_give(&sem_thread1);
60 }
61
62 /**
63 * @ingroup kernel_thread_tests
64 * @brief Test the k_thread_priority_set() API
65 *
66 * @see k_thread_priority_set(), k_thread_priority_get()
67 */
ZTEST(threads_lifecycle,test_threads_priority_set)68 ZTEST(threads_lifecycle, test_threads_priority_set)
69 {
70 int rv;
71 int prio = k_thread_priority_get(k_current_get());
72
73 /* Lower the priority of the current thread (thread1) */
74 k_thread_priority_set(k_current_get(), prio + 2);
75 rv = k_thread_priority_get(k_current_get());
76 zassert_equal(rv, prio + 2,
77 "Expected priority to be changed to %d, not %d\n",
78 prio + 2, rv);
79
80 /* Raise the priority of the current thread (thread1) */
81 k_thread_priority_set(k_current_get(), prio - 2);
82 rv = k_thread_priority_get(k_current_get());
83 zassert_equal(rv, prio - 2,
84 "Expected priority to be changed to %d, not %d\n",
85 prio - 2, rv);
86
87 /* Restore the priority of the current thread (thread1) */
88 k_thread_priority_set(k_current_get(), prio);
89 rv = k_thread_priority_get(k_current_get());
90 zassert_equal(rv, prio,
91 "Expected priority to be changed to %d, not %d\n",
92 prio, rv);
93
94 /* create thread with lower priority */
95 int thread2_prio = prio + 1;
96
97 k_tid_t thread2_id = k_thread_create(&tdata, tstack, STACK_SIZE,
98 thread2_set_prio_test,
99 NULL, NULL, NULL, thread2_prio, 0,
100 K_NO_WAIT);
101
102 /* Lower the priority of thread2 */
103 k_thread_priority_set(thread2_id, thread2_prio + 2);
104 k_sem_give(&sem_thread2);
105 k_sem_take(&sem_thread1, K_FOREVER);
106 zassert_equal(thread2_data, thread2_prio + 2,
107 "Expected priority to be changed to %d, not %d\n",
108 thread2_prio + 2, thread2_data);
109
110 /* Raise the priority of thread2 */
111 k_thread_priority_set(thread2_id, thread2_prio - 2);
112 k_sem_give(&sem_thread2);
113 k_sem_take(&sem_thread1, K_FOREVER);
114 zassert_equal(thread2_data, thread2_prio - 2,
115 "Expected priority to be changed to %d, not %d\n",
116 thread2_prio - 2, thread2_data);
117
118 /* Restore the priority of thread2 */
119 k_thread_priority_set(thread2_id, thread2_prio);
120 k_sem_give(&sem_thread2);
121 k_sem_take(&sem_thread1, K_FOREVER);
122 zassert_equal(thread2_data, thread2_prio,
123 "Expected priority to be changed to %d, not %d\n",
124 thread2_prio, thread2_data);
125
126 k_thread_join(thread2_id, K_FOREVER);
127 }
128
129 /**
130 * @ingroup kernel_thread_tests
131 * @brief Test the k_thread_priority_set() API from an ISR
132 *
133 * @see k_thread_priority_set(), k_thread_priority_get()
134 */
ZTEST(threads_lifecycle,test_isr_threads_priority_set_)135 ZTEST(threads_lifecycle, test_isr_threads_priority_set_)
136 {
137 int rv;
138 int prio = k_thread_priority_get(k_current_get());
139
140 /* Lower the priority of the current thread (thread1) */
141 prio_args.thread = k_current_get();
142 prio_args.prio = prio + 2;
143 irq_offload(test_isr, &prio_args);
144 rv = k_thread_priority_get(k_current_get());
145 zassert_equal(rv, prio + 2,
146 "Expected priority to be changed to %d, not %d\n",
147 prio + 2, rv);
148
149 /* Raise the priority of the current thread (thread1) */
150 prio_args.prio = prio - 2;
151 irq_offload(test_isr, &prio_args);
152 rv = k_thread_priority_get(k_current_get());
153 zassert_equal(rv, prio - 2,
154 "Expected priority to be changed to %d, not %d\n",
155 prio - 2, rv);
156
157 /* Restore the priority of the current thread (thread1) */
158 prio_args.prio = prio;
159 irq_offload(test_isr, &prio_args);
160 rv = k_thread_priority_get(k_current_get());
161 zassert_equal(rv, prio,
162 "Expected priority to be changed to %d, not %d\n",
163 prio, rv);
164
165 /* create thread with lower priority */
166 int thread2_prio = prio + 1;
167
168 k_tid_t thread2_id = k_thread_create(&tdata, tstack, STACK_SIZE,
169 thread2_set_prio_test,
170 NULL, NULL, NULL, thread2_prio, 0,
171 K_NO_WAIT);
172
173 /* Lower the priority of thread2 */
174 prio_args.thread = thread2_id;
175 prio_args.prio = thread2_prio + 2;
176 irq_offload(test_isr, &prio_args);
177 k_sem_give(&sem_thread2);
178 k_sem_take(&sem_thread1, K_FOREVER);
179 zassert_equal(thread2_data, thread2_prio + 2,
180 "Expected priority to be changed to %d, not %d\n",
181 thread2_prio + 2, thread2_data);
182
183 /* Raise the priority of thread2 */
184 prio_args.prio = thread2_prio - 2;
185 irq_offload(test_isr, &prio_args);
186 k_sem_give(&sem_thread2);
187 k_sem_take(&sem_thread1, K_FOREVER);
188 zassert_equal(thread2_data, thread2_prio - 2,
189 "Expected priority to be changed to %d, not %d\n",
190 thread2_prio - 2, thread2_data);
191
192 /* Restore the priority of thread2 */
193 prio_args.prio = thread2_prio;
194 irq_offload(test_isr, &prio_args);
195 k_sem_give(&sem_thread2);
196 k_sem_take(&sem_thread1, K_FOREVER);
197 zassert_equal(thread2_data, thread2_prio,
198 "Expected priority to be changed to %d, not %d\n",
199 thread2_prio, thread2_data);
200 k_thread_join(thread2_id, K_FOREVER);
201 }
202