1 /*
2  * Copyright (c) 2012-2015 Wind River Systems, Inc.
3  * Copyright (c) 2023,2024 Intel Corporation.
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 /*
9  * @file
10  * This file contains the main testing module that invokes all the tests.
11  */
12 
13 #include <zephyr/kernel.h>
14 #include <zephyr/timestamp.h>
15 #include "utils.h"
16 #include "timing_sc.h"
17 #include <zephyr/tc_util.h>
18 
19 #define STACK_SIZE (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
20 
21 uint32_t tm_off;
22 
23 BENCH_BMEM struct timestamp_data  timestamp;
24 
25 #ifdef CONFIG_USERSPACE
26 K_APPMEM_PARTITION_DEFINE(bench_mem_partition);
27 #endif
28 
29 K_THREAD_STACK_DEFINE(start_stack, START_STACK_SIZE);
30 K_THREAD_STACK_DEFINE(alt_stack, ALT_STACK_SIZE);
31 
32 K_SEM_DEFINE(pause_sem, 0, 1);
33 
34 #if (CONFIG_MP_MAX_NUM_CPUS > 1)
35 struct k_thread  busy_thread[CONFIG_MP_MAX_NUM_CPUS - 1];
36 
37 #define BUSY_THREAD_STACK_SIZE  (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
38 
39 K_THREAD_STACK_ARRAY_DEFINE(busy_thread_stack, CONFIG_MP_MAX_NUM_CPUS - 1, BUSY_THREAD_STACK_SIZE);
40 #endif
41 
42 struct k_thread  start_thread;
43 struct k_thread  alt_thread;
44 
45 int error_count; /* track number of errors */
46 
47 extern void thread_switch_yield(uint32_t num_iterations, bool is_cooperative);
48 extern void int_to_thread(uint32_t num_iterations);
49 extern void sema_test_signal(uint32_t num_iterations, uint32_t options);
50 extern void mutex_lock_unlock(uint32_t num_iterations, uint32_t options);
51 extern void sema_context_switch(uint32_t num_iterations,
52 				uint32_t start_options, uint32_t alt_options);
53 extern int thread_ops(uint32_t num_iterations, uint32_t start_options,
54 		      uint32_t alt_options);
55 extern int fifo_ops(uint32_t num_iterations, uint32_t options);
56 extern int fifo_blocking_ops(uint32_t num_iterations, uint32_t start_options,
57 			     uint32_t alt_options);
58 extern int lifo_ops(uint32_t num_iterations, uint32_t options);
59 extern int lifo_blocking_ops(uint32_t num_iterations, uint32_t start_options,
60 			     uint32_t alt_options);
61 extern int event_ops(uint32_t num_iterations, uint32_t options);
62 extern int event_blocking_ops(uint32_t num_iterations, uint32_t start_options,
63 			      uint32_t alt_options);
64 extern int condvar_blocking_ops(uint32_t num_iterations, uint32_t start_options,
65 				uint32_t alt_options);
66 extern int stack_ops(uint32_t num_iterations, uint32_t options);
67 extern int stack_blocking_ops(uint32_t num_iterations, uint32_t start_options,
68 			       uint32_t alt_options);
69 extern void heap_malloc_free(void);
70 
71 #if (CONFIG_MP_MAX_NUM_CPUS > 1)
busy_thread_entry(void * arg1,void * arg2,void * arg3)72 static void busy_thread_entry(void *arg1, void *arg2, void *arg3)
73 {
74 	while (1) {
75 	}
76 }
77 #endif
78 
test_thread(void * arg1,void * arg2,void * arg3)79 static void test_thread(void *arg1, void *arg2, void *arg3)
80 {
81 	uint32_t freq;
82 
83 	ARG_UNUSED(arg1);
84 	ARG_UNUSED(arg2);
85 	ARG_UNUSED(arg3);
86 
87 #if (CONFIG_MP_MAX_NUM_CPUS > 1)
88 	/* Spawn busy threads that will execute on the other cores */
89 
90 	for (uint32_t i = 0; i < CONFIG_MP_MAX_NUM_CPUS - 1; i++) {
91 		k_thread_create(&busy_thread[i], busy_thread_stack[i],
92 				BUSY_THREAD_STACK_SIZE, busy_thread_entry,
93 				NULL, NULL, NULL,
94 				K_HIGHEST_THREAD_PRIO, 0, K_NO_WAIT);
95 	}
96 #endif
97 
98 #ifdef CONFIG_USERSPACE
99 	k_mem_domain_add_partition(&k_mem_domain_default,
100 				   &bench_mem_partition);
101 #endif
102 
103 	timing_init();
104 
105 	bench_test_init();
106 
107 	freq = timing_freq_get_mhz();
108 
109 	TC_START("Time Measurement");
110 	TC_PRINT("Timing results: Clock frequency: %u MHz\n", freq);
111 
112 	timestamp_overhead_init(CONFIG_BENCHMARK_NUM_ITERATIONS);
113 
114 	/* Preemptive threads context switching */
115 	thread_switch_yield(CONFIG_BENCHMARK_NUM_ITERATIONS, false);
116 
117 	/* Cooperative threads context switching */
118 	thread_switch_yield(CONFIG_BENCHMARK_NUM_ITERATIONS, true);
119 
120 	int_to_thread(CONFIG_BENCHMARK_NUM_ITERATIONS);
121 
122 	/* Thread creation, starting, suspending, resuming and aborting. */
123 
124 	thread_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
125 #ifdef CONFIG_USERSPACE
126 	thread_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
127 	thread_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
128 	thread_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
129 #endif
130 
131 	fifo_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
132 #ifdef CONFIG_USERSPACE
133 	fifo_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
134 #endif
135 
136 	fifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
137 #ifdef CONFIG_USERSPACE
138 	fifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
139 	fifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
140 	fifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
141 #endif
142 
143 
144 	lifo_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
145 #ifdef CONFIG_USERSPACE
146 	lifo_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
147 #endif
148 
149 	lifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
150 #ifdef CONFIG_USERSPACE
151 	lifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
152 	lifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
153 	lifo_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
154 #endif
155 
156 	event_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
157 #ifdef CONFIG_USERSPACE
158 	event_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
159 #endif
160 
161 	event_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
162 #ifdef CONFIG_USERSPACE
163 	event_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
164 	event_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
165 	event_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
166 #endif
167 
168 	sema_test_signal(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
169 #ifdef CONFIG_USERSPACE
170 	sema_test_signal(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
171 #endif
172 
173 	sema_context_switch(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
174 #ifdef CONFIG_USERSPACE
175 	sema_context_switch(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
176 	sema_context_switch(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
177 	sema_context_switch(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
178 #endif
179 
180 	condvar_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
181 #ifdef CONFIG_USERSPACE
182 	condvar_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
183 	condvar_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
184 	condvar_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
185 #endif
186 
187 	stack_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
188 #ifdef CONFIG_USERSPACE
189 	stack_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
190 #endif
191 
192 	stack_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, 0);
193 #ifdef CONFIG_USERSPACE
194 	stack_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, 0, K_USER);
195 	stack_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, 0);
196 	stack_blocking_ops(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER, K_USER);
197 #endif
198 
199 	mutex_lock_unlock(CONFIG_BENCHMARK_NUM_ITERATIONS, 0);
200 #ifdef CONFIG_USERSPACE
201 	mutex_lock_unlock(CONFIG_BENCHMARK_NUM_ITERATIONS, K_USER);
202 #endif
203 
204 	heap_malloc_free();
205 
206 	TC_END_REPORT(error_count);
207 }
208 
209 K_THREAD_DEFINE(test_thread_id, STACK_SIZE, test_thread, NULL, NULL, NULL,
210 		K_PRIO_PREEMPT(10), 0, 0);
211 
main(void)212 int main(void)
213 {
214 	k_thread_join(test_thread_id, K_FOREVER);
215 	return 0;
216 }
217