1 /*
2 * Copyright (c) 2023, Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/sys/mem_blocks.h>
9
10 SYS_MEM_BLOCKS_DEFINE(block1, 32, 4, 16);
11
12 K_MEM_SLAB_DEFINE(slab1, 32, 4, 16);
13 static char slab2_buffer[256] __aligned(8);
14 struct k_mem_slab slab2;
15
16 K_TIMER_DEFINE(timer1, NULL, NULL);
17 struct k_timer timer2;
18
19 K_STACK_DEFINE(stack1, 8);
20 static struct k_stack stack2;
21 stack_data_t stack2_buffer[8];
22
23 static K_FIFO_DEFINE(fifo1);
24 static struct k_fifo fifo2;
25
26 static K_LIFO_DEFINE(lifo1);
27 static struct k_lifo lifo2;
28
29 K_PIPE_DEFINE(pipe1, 16, 8);
30 static struct k_pipe pipe2;
31 static char pipe2_buffer[16];
32
33 K_MSGQ_DEFINE(msgq1, 16, 4, 8);
34 static struct k_msgq msgq2;
35 static char msgq2_buffer[16];
36
37 static K_MBOX_DEFINE(mbox1);
38 static struct k_mbox mbox2;
39
40 static K_CONDVAR_DEFINE(condvar1);
41 static struct k_condvar condvar2;
42
43 static K_EVENT_DEFINE(event1);
44 static struct k_event event2;
45
46 static K_MUTEX_DEFINE(mutex1);
47 static struct k_mutex mutex2;
48
49 static K_SEM_DEFINE(sem1, 0, 1);
50 static struct k_sem sem2;
51
52 static void thread_entry(void *, void *, void *);
53 K_THREAD_DEFINE(thread1, 512 + CONFIG_TEST_EXTRA_STACK_SIZE,
54 thread_entry, NULL, NULL, NULL,
55 K_HIGHEST_THREAD_PRIO, 0, 0);
56 static struct k_thread thread2;
57 K_THREAD_STACK_DEFINE(thread2_stack, 512 + CONFIG_TEST_EXTRA_STACK_SIZE);
58
59 struct obj_core_find_data {
60 struct k_obj_core *obj_core; /* Object core to search for */
61 };
62
thread_entry(void * p1,void * p2,void * p3)63 static void thread_entry(void *p1, void *p2, void *p3)
64 {
65 k_sem_take(&sem1, K_FOREVER);
66 }
67
obj_core_find_op(struct k_obj_core * obj_core,void * data)68 static int obj_core_find_op(struct k_obj_core *obj_core, void *data)
69 {
70 struct obj_core_find_data *find_data = data;
71
72 if (find_data->obj_core == obj_core) {
73
74 /* Object core found. Abort the search. */
75
76 return 1;
77 }
78
79 /* Object core not found--continue searching. */
80
81 return 0;
82 }
83
common_obj_core_test(uint32_t type_id,const char * str,struct k_obj_core * static_obj_core,struct k_obj_core * dyn_obj_core)84 static void common_obj_core_test(uint32_t type_id, const char *str,
85 struct k_obj_core *static_obj_core,
86 struct k_obj_core *dyn_obj_core)
87 {
88 struct k_obj_type *obj_type;
89 struct obj_core_find_data walk_data;
90 int status;
91
92 obj_type = k_obj_type_find(type_id);
93
94 zassert_not_null(obj_type, "%s object type not found\n", str);
95
96 /* Search for statically initialized object */
97
98 if (static_obj_core != NULL) {
99 walk_data.obj_core = static_obj_core;
100 status = k_obj_type_walk_locked(obj_type, obj_core_find_op,
101 &walk_data);
102 zassert_equal(status, 1,
103 "static %s not found with locked walk\n", str);
104
105 status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op,
106 &walk_data);
107 zassert_equal(status, 1,
108 "static %s not found with unlocked walk\n", str);
109 }
110
111 /* Search for dynamically initialized object */
112
113 if (dyn_obj_core != NULL) {
114 walk_data.obj_core = dyn_obj_core;
115 status = k_obj_type_walk_locked(obj_type, obj_core_find_op,
116 &walk_data);
117 zassert_equal(status, 1,
118 "dynamic %s not found with locked walk\n", str);
119
120 status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op,
121 &walk_data);
122 zassert_equal(status, 1,
123 "dynamic %s not found with unlocked walk\n", str);
124 }
125 }
126
ZTEST(obj_core,test_obj_core_thread)127 ZTEST(obj_core, test_obj_core_thread)
128 {
129 k_thread_create(&thread2, thread2_stack,
130 K_THREAD_STACK_SIZEOF(thread2_stack), thread_entry,
131 NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT);
132
133 common_obj_core_test(K_OBJ_TYPE_THREAD_ID, "thread",
134 K_OBJ_CORE(thread1), K_OBJ_CORE(&thread2));
135
136 /* Terminate both thread1 and thread 2 */
137
138 k_thread_abort(thread1);
139 k_thread_abort(&thread2);
140
141 /*
142 * Neither thread1 nor thread2 should be in the thread object type's
143 * list of threads anymore. Verify this.
144 */
145
146 struct k_obj_type *obj_type;
147 struct obj_core_find_data walk_data;
148 int status;
149
150 obj_type = k_obj_type_find(K_OBJ_TYPE_THREAD_ID);
151
152 zassert_not_null(obj_type, "thread object type not found\n");
153
154 /* Search for statically initialized object */
155
156 walk_data.obj_core = K_OBJ_CORE(thread1);
157 status = k_obj_type_walk_locked(obj_type, obj_core_find_op,
158 &walk_data);
159 zassert_equal(status, 0, "static thread found with locked walk\n");
160
161 status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op,
162 &walk_data);
163 zassert_equal(status, 0, "static thread found with unlocked walk\n");
164
165 walk_data.obj_core = K_OBJ_CORE(&thread2);
166 status = k_obj_type_walk_locked(obj_type, obj_core_find_op,
167 &walk_data);
168 zassert_equal(status, 0, "dynamic thread found with locked walk\n");
169
170 status = k_obj_type_walk_unlocked(obj_type, obj_core_find_op,
171 &walk_data);
172 zassert_equal(status, 0, "dynamic thread found with unlocked walk\n");
173 }
174
ZTEST(obj_core,test_obj_core_system)175 ZTEST(obj_core, test_obj_core_system)
176 {
177 int i;
178 char cpu_str[16];
179
180 /*
181 * Use the existing object cores in the _cpu and z_kerenl structures
182 * as we should not be creating new ones.
183 */
184
185 for (i = 0; i < CONFIG_MP_MAX_NUM_CPUS; i++) {
186 sprintf(cpu_str, "CPU%d", i);
187 common_obj_core_test(K_OBJ_TYPE_CPU_ID, cpu_str,
188 K_OBJ_CORE(&_kernel.cpus[i]), NULL);
189 }
190
191 common_obj_core_test(K_OBJ_TYPE_KERNEL_ID, "_kernel",
192 K_OBJ_CORE(&_kernel), NULL);
193 }
194
ZTEST(obj_core,test_obj_core_sys_mem_block)195 ZTEST(obj_core, test_obj_core_sys_mem_block)
196 {
197 common_obj_core_test(K_OBJ_TYPE_MEM_BLOCK_ID, "memory block",
198 K_OBJ_CORE(&block1), NULL);
199 }
200
ZTEST(obj_core,test_obj_core_mem_slab)201 ZTEST(obj_core, test_obj_core_mem_slab)
202 {
203 k_mem_slab_init(&slab2, slab2_buffer, 32, 8);
204 common_obj_core_test(K_OBJ_TYPE_MEM_SLAB_ID, "memory slab",
205 K_OBJ_CORE(&slab1), K_OBJ_CORE(&slab2));
206 }
207
ZTEST(obj_core,test_obj_core_timer)208 ZTEST(obj_core, test_obj_core_timer)
209 {
210 k_timer_init(&timer2, NULL, NULL);
211 common_obj_core_test(K_OBJ_TYPE_TIMER_ID, "timer",
212 K_OBJ_CORE(&timer1), K_OBJ_CORE(&timer2));
213 }
214
ZTEST(obj_core,test_obj_core_stack)215 ZTEST(obj_core, test_obj_core_stack)
216 {
217 k_stack_init(&stack2, stack2_buffer, 8);
218 common_obj_core_test(K_OBJ_TYPE_STACK_ID, "stack",
219 K_OBJ_CORE(&stack1), K_OBJ_CORE(&stack2));
220 }
221
ZTEST(obj_core,test_obj_core_fifo)222 ZTEST(obj_core, test_obj_core_fifo)
223 {
224 k_fifo_init(&fifo2);
225 common_obj_core_test(K_OBJ_TYPE_FIFO_ID, "FIFO",
226 K_OBJ_CORE(&fifo1), K_OBJ_CORE(&fifo2));
227 }
228
ZTEST(obj_core,test_obj_core_lifo)229 ZTEST(obj_core, test_obj_core_lifo)
230 {
231 k_lifo_init(&lifo2);
232 common_obj_core_test(K_OBJ_TYPE_LIFO_ID, "LIFO",
233 K_OBJ_CORE(&lifo1), K_OBJ_CORE(&lifo2));
234 }
235
ZTEST(obj_core,test_obj_core_pipe)236 ZTEST(obj_core, test_obj_core_pipe)
237 {
238 k_pipe_init(&pipe2, pipe2_buffer, sizeof(pipe2_buffer));
239 common_obj_core_test(K_OBJ_TYPE_PIPE_ID, "pipe",
240 K_OBJ_CORE(&pipe1), K_OBJ_CORE(&pipe2));
241 }
242
ZTEST(obj_core,test_obj_core_msgq)243 ZTEST(obj_core, test_obj_core_msgq)
244 {
245 k_msgq_init(&msgq2, msgq2_buffer, 4, 4);
246 common_obj_core_test(K_OBJ_TYPE_MSGQ_ID, "message queue",
247 K_OBJ_CORE(&msgq1), K_OBJ_CORE(&msgq2));
248 }
249
ZTEST(obj_core,test_obj_core_mbox)250 ZTEST(obj_core, test_obj_core_mbox)
251 {
252 k_mbox_init(&mbox2);
253 common_obj_core_test(K_OBJ_TYPE_MBOX_ID, "mailbox",
254 K_OBJ_CORE(&mbox1), K_OBJ_CORE(&mbox2));
255 }
256
ZTEST(obj_core,test_obj_core_condvar)257 ZTEST(obj_core, test_obj_core_condvar)
258 {
259 k_condvar_init(&condvar2);
260 common_obj_core_test(K_OBJ_TYPE_CONDVAR_ID, "condition variable",
261 K_OBJ_CORE(&condvar1), K_OBJ_CORE(&condvar2));
262 }
263
ZTEST(obj_core,test_obj_core_event)264 ZTEST(obj_core, test_obj_core_event)
265 {
266 k_event_init(&event2);
267 common_obj_core_test(K_OBJ_TYPE_EVENT_ID, "event",
268 K_OBJ_CORE(&event1), K_OBJ_CORE(&event2));
269 }
270
ZTEST(obj_core,test_obj_core_mutex)271 ZTEST(obj_core, test_obj_core_mutex)
272 {
273 k_mutex_init(&mutex2);
274 common_obj_core_test(K_OBJ_TYPE_MUTEX_ID, "mutex",
275 K_OBJ_CORE(&mutex1), K_OBJ_CORE(&mutex2));
276 }
277
ZTEST(obj_core,test_obj_core_sem)278 ZTEST(obj_core, test_obj_core_sem)
279 {
280 k_sem_init(&sem2, 0, 1);
281
282 common_obj_core_test(K_OBJ_TYPE_SEM_ID, "semaphore",
283 K_OBJ_CORE(&sem1), K_OBJ_CORE(&sem2));
284 }
285
286 ZTEST_SUITE(obj_core, NULL, NULL,
287 ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
288