1 /* master.c */
2 
3 /*
4  * Copyright (c) 1997-2010,2013-2015 Wind River Systems, Inc.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 /*
10  * File Naming information.
11  * ------------------------
12  *	Files that end with:
13  *		_B : Is a file that contains a benchmark function
14  *		_R : Is a file that contains the receiver task
15  *			 of a benchmark function
16  */
17 #include <zephyr/tc_util.h>
18 #include "master.h"
19 
20 #define RECV_STACK_SIZE  (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
21 #define TEST_STACK_SIZE  (1024 + CONFIG_TEST_EXTRA_STACK_SIZE)
22 
23 BENCH_BMEM char msg[MAX_MSG];
24 BENCH_BMEM char data_bench[MESSAGE_SIZE];
25 
26 BENCH_DMEM struct k_pipe *test_pipes[] = {&PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF};
27 BENCH_BMEM char sline[SLINE_LEN + 1];
28 
29 /*
30  * Time in timer cycles necessary to read time.
31  * Used for correction in time measurements.
32  */
33 uint32_t tm_off;
34 
35 static BENCH_DMEM char *test_type_str[] = {
36 	"|                  K E R N E L - - > K E R N E L                   |          |\n",
37 	"|                  K E R N E L - - >   U S E R                     |          |\n",
38 	"|                    U S E R   - - > K E R N E L                   |          |\n",
39 	"|                    U S E R   - - >   U S E R                     |          |\n"
40 };
41 
42 /********************************************************************/
43 /* static allocation  */
44 
45 static struct k_thread test_thread;
46 static struct k_thread recv_thread;
47 K_THREAD_STACK_DEFINE(test_stack, TEST_STACK_SIZE);
48 K_THREAD_STACK_DEFINE(recv_stack, RECV_STACK_SIZE);
49 
50 #ifdef CONFIG_USERSPACE
51 K_APPMEM_PARTITION_DEFINE(bench_mem_partition);
52 #endif
53 
54 K_MSGQ_DEFINE(DEMOQX1, 1, 500, 4);
55 K_MSGQ_DEFINE(DEMOQX4, 4, 500, 4);
56 K_MSGQ_DEFINE(DEMOQX192, 192, 500, 4);
57 K_MSGQ_DEFINE(MB_COMM, 12, 1, 4);
58 K_MSGQ_DEFINE(CH_COMM, 12, 1, 4);
59 
60 K_MEM_SLAB_DEFINE(MAP1, 16, 2, 4);
61 
62 K_SEM_DEFINE(SEM0, 0, 1);
63 K_SEM_DEFINE(SEM1, 0, 1);
64 K_SEM_DEFINE(SEM2, 0, 1);
65 K_SEM_DEFINE(SEM3, 0, 1);
66 K_SEM_DEFINE(SEM4, 0, 1);
67 K_SEM_DEFINE(STARTRCV, 0, 1);
68 
69 K_MBOX_DEFINE(MAILB1);
70 
71 K_MUTEX_DEFINE(DEMO_MUTEX);
72 
73 K_PIPE_DEFINE(PIPE_NOBUFF, 0, 4);
74 K_PIPE_DEFINE(PIPE_SMALLBUFF, 256, 4);
75 K_PIPE_DEFINE(PIPE_BIGBUFF, 4096, 4);
76 
77 /*
78  * Custom syscalls
79  */
80 
81 /**
82  * @brief Obtain a timestamp
83  *
84  * Architecture timestamp routines often require MMIO that is not mapped to
85  * the user threads. Use a custom system call to get the timestamp.
86  */
z_impl_timing_timestamp_get(void)87 timing_t z_impl_timing_timestamp_get(void)
88 {
89 	return timing_counter_get();
90 }
91 
92 #ifdef CONFIG_USERSPACE
z_vrfy_timing_timestamp_get(void)93 static timing_t z_vrfy_timing_timestamp_get(void)
94 {
95 	return z_impl_timing_timestamp_get();
96 }
97 
98 #include <zephyr/syscalls/timing_timestamp_get_mrsh.c>
99 #endif
100 
101 /*
102  * Main test
103  */
104 
105 /**
106  * @brief Entry point for test thread
107  */
test_thread_entry(void * p1,void * p2,void * p3)108 static void test_thread_entry(void *p1, void *p2, void *p3)
109 {
110 	bool skip_mem_and_mbox = (bool)(uintptr_t)(p2);
111 
112 	ARG_UNUSED(p3);
113 
114 	PRINT_STRING("\n");
115 	PRINT_STRING(dashline);
116 	PRINT_STRING("|          S I M P L E   S E R V I C E    "
117 		     "M E A S U R E M E N T S  |  nsec    |\n");
118 #ifdef CONFIG_USERSPACE
119 	PRINT_STRING((const char *)p1);
120 #endif
121 	PRINT_STRING(dashline);
122 
123 	message_queue_test();
124 	sema_test();
125 	mutex_test();
126 
127 	if (!skip_mem_and_mbox) {
128 		memorymap_test();
129 		mailbox_test();
130 	}
131 
132 	pipe_test();
133 }
134 
135 /**
136  * @brief Perform all benchmarks
137  */
main(void)138 int main(void)
139 {
140 	int  priority;
141 
142 	priority = k_thread_priority_get(k_current_get());
143 
144 #ifdef CONFIG_USERSPACE
145 	k_mem_domain_add_partition(&k_mem_domain_default,
146 				   &bench_mem_partition);
147 #endif
148 
149 	bench_test_init();
150 
151 	timing_init();
152 
153 	timing_start();
154 
155 	/* ********* All threads are kernel threads ********** */
156 
157 	k_thread_create(&test_thread, test_stack,
158 			K_THREAD_STACK_SIZEOF(test_stack),
159 			test_thread_entry,
160 			test_type_str[0], (void *)(uintptr_t)false, NULL,
161 			priority, 0, K_FOREVER);
162 
163 	k_thread_create(&recv_thread, recv_stack,
164 			K_THREAD_STACK_SIZEOF(recv_stack),
165 			recvtask, (void *)(uintptr_t)false, NULL, NULL,
166 			5, 0, K_FOREVER);
167 
168 	k_thread_start(&recv_thread);
169 	k_thread_start(&test_thread);
170 
171 	k_thread_join(&test_thread, K_FOREVER);
172 	k_thread_abort(&recv_thread);
173 
174 #ifdef CONFIG_USERSPACE
175 	/* ****** Main thread is kernel, receiver is user thread ******* */
176 
177 	k_thread_create(&test_thread, test_stack,
178 			K_THREAD_STACK_SIZEOF(test_stack),
179 			test_thread_entry,
180 			test_type_str[1], (void *)(uintptr_t)true, NULL,
181 			priority, 0, K_FOREVER);
182 
183 	k_thread_create(&recv_thread, recv_stack,
184 			K_THREAD_STACK_SIZEOF(recv_stack),
185 			recvtask, (void *)(uintptr_t)true, NULL, NULL,
186 			5, K_USER, K_FOREVER);
187 
188 	k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192,
189 			      &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3,
190 			      &SEM4, &STARTRCV, &DEMO_MUTEX,
191 			      &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF);
192 
193 	k_thread_start(&recv_thread);
194 	k_thread_start(&test_thread);
195 
196 	k_thread_join(&test_thread, K_FOREVER);
197 	k_thread_abort(&recv_thread);
198 
199 	/* ****** Main thread is user, receiver is kernel thread ******* */
200 
201 	k_thread_create(&test_thread, test_stack,
202 			K_THREAD_STACK_SIZEOF(test_stack),
203 			test_thread_entry,
204 			test_type_str[2], (void *)(uintptr_t)true, NULL,
205 			priority, K_USER, K_FOREVER);
206 
207 	k_thread_create(&recv_thread, recv_stack,
208 			K_THREAD_STACK_SIZEOF(recv_stack),
209 			recvtask, (void *)(uintptr_t)true, NULL, NULL,
210 			5, 0, K_FOREVER);
211 
212 	k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192,
213 			      &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3,
214 			      &SEM4, &STARTRCV, &DEMO_MUTEX,
215 			      &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF);
216 
217 	k_thread_start(&recv_thread);
218 	k_thread_start(&test_thread);
219 
220 	k_thread_join(&test_thread, K_FOREVER);
221 	k_thread_abort(&recv_thread);
222 
223 	/* ********* All threads are user threads ********** */
224 
225 	k_thread_create(&test_thread, test_stack,
226 			K_THREAD_STACK_SIZEOF(test_stack),
227 			test_thread_entry,
228 			test_type_str[3], (void *)(uintptr_t)true, NULL,
229 			priority, K_USER, K_FOREVER);
230 
231 	k_thread_create(&recv_thread, recv_stack,
232 			K_THREAD_STACK_SIZEOF(recv_stack),
233 			recvtask, (void *)(uintptr_t)true, NULL, NULL,
234 			5, K_USER, K_FOREVER);
235 
236 	k_thread_access_grant(&test_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192,
237 			      &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3,
238 			      &SEM4, &STARTRCV, &DEMO_MUTEX,
239 			      &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF);
240 	k_thread_access_grant(&recv_thread, &DEMOQX1, &DEMOQX4, &DEMOQX192,
241 			      &MB_COMM, &CH_COMM, &SEM0, &SEM1, &SEM2, &SEM3,
242 			      &SEM4, &STARTRCV, &DEMO_MUTEX,
243 			      &PIPE_NOBUFF, &PIPE_SMALLBUFF, &PIPE_BIGBUFF);
244 
245 	k_thread_start(&recv_thread);
246 	k_thread_start(&test_thread);
247 
248 	k_thread_join(&test_thread, K_FOREVER);
249 	k_thread_abort(&recv_thread);
250 #endif /* CONFIG_USERSPACE */
251 
252 	timing_stop();
253 
254 	PRINT_STRING("|         END OF TESTS                     "
255 		     "                                   |\n");
256 	PRINT_STRING(dashline);
257 	PRINT_STRING("PROJECT EXECUTION SUCCESSFUL\n");
258 	TC_PRINT_RUNID;
259 
260 	return 0;
261 }
262