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