1 /*
2  * Copyright (c) 2016 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/ztest.h>
8 
9 K_SEM_DEFINE(static_preem_start_sema, 0, 1);
10 K_SEM_DEFINE(preem_start_sema, 0, 1);
11 K_SEM_DEFINE(static_coop_start_sema, 0, 1);
12 K_SEM_DEFINE(coop_start_sema, 0, 1);
13 
14 K_SEM_DEFINE(end_sema, 0, 1);
15 /*macro definition*/
16 #define INIT_COOP_PRIO -2
17 #define INIT_COOP_STACK_SIZE (500 + CONFIG_TEST_EXTRA_STACK_SIZE)
18 #define INIT_COOP_P1			((void *)0xFFFF0000)
19 #define INIT_COOP_P2			((void *)0xCDEF)
20 #define INIT_COOP_P3_static		((void *)&static_coop_start_sema)
21 #define INIT_COOP_P3			((void *)&coop_start_sema)
22 #define INIT_COOP_OPTION (K_USER | K_INHERIT_PERMS)
23 #define INIT_COOP_DELAY 2000
24 #define INIT_PREEMPT_PRIO 1
25 #define INIT_PREEMPT_STACK_SIZE (499 + CONFIG_TEST_EXTRA_STACK_SIZE)
26 #define INIT_PREEMPT_P1			((void *)5)
27 #define INIT_PREEMPT_P2			((void *)6)
28 #define INIT_PREEMPT_P3_static	((void *)&static_preem_start_sema)
29 #define INIT_PREEMPT_P3			((void *)&preem_start_sema)
30 #define INIT_PREEMPT_OPTION (K_USER | K_INHERIT_PERMS)
31 #define INIT_PREEMPT_DELAY 0
32 
33 static void thread_entry(void *p1, void *p2, void *p3);
34 
35 K_THREAD_DEFINE(T_KDEFINE_COOP_THREAD, INIT_COOP_STACK_SIZE,
36 		thread_entry, INIT_COOP_P1, INIT_COOP_P2, INIT_COOP_P3_static,
37 		INIT_COOP_PRIO, INIT_COOP_OPTION, INIT_COOP_DELAY);
38 
39 K_THREAD_DEFINE(T_KDEFINE_PREEMPT_THREAD, INIT_PREEMPT_STACK_SIZE,
40 		thread_entry, INIT_PREEMPT_P1, INIT_PREEMPT_P2, INIT_PREEMPT_P3_static,
41 		INIT_PREEMPT_PRIO, INIT_PREEMPT_OPTION, INIT_PREEMPT_DELAY);
42 
43 K_THREAD_ACCESS_GRANT(T_KDEFINE_COOP_THREAD, &static_preem_start_sema,
44 	 &preem_start_sema, &static_coop_start_sema, &coop_start_sema, &end_sema);
45 K_THREAD_ACCESS_GRANT(T_KDEFINE_PREEMPT_THREAD, &static_preem_start_sema,
46 	 &preem_start_sema, &static_coop_start_sema, &coop_start_sema, &end_sema);
47 
48 /*local variables*/
49 static K_THREAD_STACK_DEFINE(stack_coop, INIT_COOP_STACK_SIZE);
50 static K_THREAD_STACK_DEFINE(stack_preempt, INIT_PREEMPT_STACK_SIZE);
51 static struct k_thread thread_coop;
52 static struct k_thread thread_preempt;
53 static ZTEST_BMEM uint64_t t_create;
54 static ZTEST_BMEM struct thread_data {
55 	int init_prio;
56 	int32_t init_delay;
57 	void *init_p1;
58 	void *init_p2;
59 	void *init_p3;
60 } expected;
61 
62 /*entry routines*/
thread_entry(void * p1,void * p2,void * p3)63 static void thread_entry(void *p1, void *p2, void *p3)
64 {
65 	if (t_create) {
66 		uint64_t t_delay = k_uptime_get() - t_create;
67 		/**TESTPOINT: check delay start*/
68 		zassert_true(t_delay >= expected.init_delay,
69 			     "k_thread_create delay start failed");
70 	}
71 
72 	k_sem_take(p3, K_FOREVER);
73 
74 	k_tid_t tid = k_current_get();
75 	/**TESTPOINT: check priority and params*/
76 	zassert_equal(k_thread_priority_get(tid), expected.init_prio);
77 	zassert_equal(p1, expected.init_p1);
78 	zassert_equal(p2, expected.init_p2);
79 	zassert_equal(p3, expected.init_p3);
80 	/*option, stack size, not checked, no public API to get these values*/
81 
82 	k_sem_give(&end_sema);
83 }
84 
85 /**
86  * @addtogroup kernel_thread_tests
87  * @{
88  */
89 
90 /**
91  * @brief test preempt thread initialization via K_THREAD_DEFINE
92  *
93  * @see #K_THREAD_DEFINE(x)
94  *
95  * @ingroup kernel_thread_tests
96  */
ZTEST_USER(thread_init,test_kdefine_preempt_thread)97 ZTEST_USER(thread_init, test_kdefine_preempt_thread)
98 {
99 	/*static thread created time unknown, skip it*/
100 	t_create = 0U;
101 	expected.init_p1 = INIT_PREEMPT_P1;
102 	expected.init_p2 = INIT_PREEMPT_P2;
103 	expected.init_p3 = INIT_PREEMPT_P3_static;
104 	expected.init_prio = INIT_PREEMPT_PRIO;
105 	expected.init_delay = INIT_PREEMPT_DELAY;
106 	k_sem_reset(&end_sema);
107 
108 	/*signal thread to start*/
109 	k_sem_give(&static_preem_start_sema);
110 	/*wait for thread to exit*/
111 	k_sem_take(&end_sema, K_FOREVER);
112 }
113 
114 /**
115  * @brief test coop thread initialization via K_THREAD_DEFINE
116  *
117  * @ingroup kernel_thread_tests
118  *
119  * @see #K_THREAD_DEFINE(x)
120  */
ZTEST_USER(thread_init,test_kdefine_coop_thread)121 ZTEST_USER(thread_init, test_kdefine_coop_thread)
122 {
123 	/*static thread creation time unknown, skip it*/
124 	t_create = 0U;
125 	expected.init_p1 = INIT_COOP_P1;
126 	expected.init_p2 = INIT_COOP_P2;
127 	expected.init_p3 = INIT_COOP_P3_static;
128 	expected.init_prio = INIT_COOP_PRIO;
129 	expected.init_delay = INIT_COOP_DELAY;
130 	k_sem_reset(&end_sema);
131 
132 	/*signal thread to start*/
133 	k_sem_give(&static_coop_start_sema);
134 	/*wait for thread to exit*/
135 	k_sem_take(&end_sema, K_FOREVER);
136 }
137 
138 /**
139  * @brief test preempt thread initialization via k_thread_create
140  *
141  * @ingroup kernel_thread_tests
142  *
143  * @see k_thread_create()
144  */
ZTEST_USER(thread_init,test_kinit_preempt_thread)145 ZTEST_USER(thread_init, test_kinit_preempt_thread)
146 {
147 	/*create preempt thread*/
148 	k_tid_t pthread = k_thread_create(&thread_preempt, stack_preempt,
149 					  INIT_PREEMPT_STACK_SIZE, thread_entry, INIT_PREEMPT_P1,
150 					  INIT_PREEMPT_P2, INIT_PREEMPT_P3, INIT_PREEMPT_PRIO,
151 					  INIT_PREEMPT_OPTION,
152 					  K_MSEC(INIT_PREEMPT_DELAY));
153 
154 	/*record time stamp of thread creation*/
155 	t_create = k_uptime_get();
156 	zassert_not_null(pthread, "thread creation failed");
157 
158 	expected.init_p1 = INIT_PREEMPT_P1;
159 	expected.init_p2 = INIT_PREEMPT_P2;
160 	expected.init_p3 = INIT_PREEMPT_P3;
161 	expected.init_prio = INIT_PREEMPT_PRIO;
162 	expected.init_delay = INIT_PREEMPT_DELAY;
163 	k_sem_reset(&end_sema);
164 
165 	/*signal thread to start*/
166 	k_sem_give(&preem_start_sema);
167 	/*wait for thread to exit*/
168 	k_sem_take(&end_sema, K_FOREVER);
169 }
170 
171 /**
172  * @brief test coop thread initialization via k_thread_create
173  *
174  * @ingroup kernel_thread_tests
175  *
176  * @see k_thread_create()
177  */
ZTEST(thread_init,test_kinit_coop_thread)178 ZTEST(thread_init, test_kinit_coop_thread)
179 {
180 	if (!(IS_ENABLED(CONFIG_USERSPACE))) {
181 		ztest_test_skip();
182 	}
183 
184 	/*create coop thread*/
185 	k_tid_t pthread = k_thread_create(&thread_coop, stack_coop,
186 			  INIT_COOP_STACK_SIZE, thread_entry, INIT_COOP_P1,
187 			  INIT_COOP_P2, INIT_COOP_P3, INIT_COOP_PRIO,
188 			  INIT_COOP_OPTION, K_MSEC(INIT_COOP_DELAY));
189 
190 	/*record time stamp of thread creation*/
191 	t_create = k_uptime_get();
192 	zassert_not_null(pthread, "thread spawn failed");
193 
194 	expected.init_p1 = INIT_COOP_P1;
195 	expected.init_p2 = INIT_COOP_P2;
196 	expected.init_p3 = INIT_COOP_P3;
197 	expected.init_prio = INIT_COOP_PRIO;
198 	expected.init_delay = INIT_COOP_DELAY;
199 	k_sem_reset(&end_sema);
200 
201 	/*signal thread to start*/
202 	k_sem_give(&coop_start_sema);
203 	/*wait for thread to exit*/
204 	k_sem_take(&end_sema, K_FOREVER);
205 }
206 
207 
208 /**
209  * @}
210  */
211 
212 /*test case main entry*/
thread_init_setup(void)213 void *thread_init_setup(void)
214 {
215 	k_thread_access_grant(k_current_get(), &thread_preempt, &stack_preempt,
216 				 &static_preem_start_sema, &preem_start_sema,
217 				 &static_coop_start_sema, &coop_start_sema, &end_sema);
218 #ifdef CONFIG_USERSPACE
219 	k_mem_domain_add_thread(&k_mem_domain_default, T_KDEFINE_COOP_THREAD);
220 	k_mem_domain_add_thread(&k_mem_domain_default, T_KDEFINE_PREEMPT_THREAD);
221 #endif
222 
223 	return NULL;
224 }
225 
226 ZTEST_SUITE(thread_init, NULL, thread_init_setup, NULL, NULL, NULL);
227