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