1 /* stack.c */
2 
3 /*
4  * Copyright (c) 1997-2010, 2013-2014 Wind River Systems, Inc.
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 
9 #include "syskernel.h"
10 
11 struct k_stack  stack_1;
12 struct k_stack  stack_2;
13 
14 stack_data_t stack1[2];
15 stack_data_t stack2[2];
16 
17 /**
18  *
19  * @brief Initialize stacks for the test
20  *
21  * @return N/A
22  *
23  */
stack_test_init(void)24 void stack_test_init(void)
25 {
26 	k_stack_init(&stack_1, stack1, 2);
27 	k_stack_init(&stack_2, stack2, 2);
28 }
29 
30 
31 /**
32  *
33  * @brief Stack test thread
34  *
35  * @param par1   Ignored parameter.
36  * @param par2   Number of test loops.
37  * @param par3	 Unused
38  *
39  * @return N/A
40  *
41  */
stack_thread1(void * par1,void * par2,void * par3)42 void stack_thread1(void *par1, void *par2, void *par3)
43 {
44 	int num_loops = POINTER_TO_INT(par2) / 2;
45 	int i;
46 	stack_data_t data;
47 
48 	ARG_UNUSED(par1);
49 	ARG_UNUSED(par3);
50 
51 	for (i = 0; i < num_loops; i++) {
52 		k_stack_pop(&stack_1, &data, K_FOREVER);
53 		if (data != 2 * i) {
54 			break;
55 		}
56 		data = 2 * i;
57 		k_stack_push(&stack_2, data);
58 		k_stack_pop(&stack_1, &data, K_FOREVER);
59 		if (data != 2 * i + 1) {
60 			break;
61 		}
62 		data = 2 * i + 1;
63 		k_stack_push(&stack_2, data);
64 	}
65 }
66 
67 
68 /**
69  *
70  * @brief Stack test thread
71  *
72  * @param par1   Address of the counter.
73  * @param par2   Number of test cycles.
74  * @param par3	 Unused
75  *
76  * @return N/A
77  *
78  */
stack_thread2(void * par1,void * par2,void * par3)79 void stack_thread2(void *par1, void *par2, void *par3)
80 {
81 	int i;
82 	stack_data_t data;
83 	int *pcounter = par1;
84 	int num_loops = POINTER_TO_INT(par2);
85 
86 	ARG_UNUSED(par3);
87 
88 	for (i = 0; i < num_loops; i++) {
89 		data = i;
90 		k_stack_push(&stack_1, data);
91 		k_stack_pop(&stack_2, &data, K_FOREVER);
92 		if (data != i) {
93 			break;
94 		}
95 		(*pcounter)++;
96 	}
97 }
98 
99 
100 /**
101  *
102  * @brief Stack test thread
103  *
104  * @param par1   Address of the counter.
105  * @param par2   Number of test cycles.
106  * @param par3	 Unused
107  *
108  * @return N/A
109  *
110  */
stack_thread3(void * par1,void * par2,void * par3)111 void stack_thread3(void *par1, void *par2, void *par3)
112 {
113 	int i;
114 	stack_data_t data;
115 	int *pcounter = par1;
116 	int num_loops = POINTER_TO_INT(par2);
117 
118 	ARG_UNUSED(par3);
119 
120 	for (i = 0; i < num_loops; i++) {
121 		data = i;
122 		k_stack_push(&stack_1, data);
123 		data = 0xffffffff;
124 
125 		while (k_stack_pop(&stack_2, &data,
126 					     K_NO_WAIT) != 0) {
127 			k_yield();
128 		}
129 		if (data != i) {
130 			break;
131 		}
132 		(*pcounter)++;
133 	}
134 }
135 
136 
137 /**
138  *
139  * @brief The main test entry
140  *
141  * @return 1 if success and 0 on failure
142  *
143  */
stack_test(void)144 int stack_test(void)
145 {
146 	uint32_t t;
147 	int i = 0;
148 	int return_value = 0;
149 
150 	/* test get wait & put stack functions between co-op threads */
151 	fprintf(output_file, sz_test_case_fmt,
152 			"Stack #1");
153 	fprintf(output_file, sz_description,
154 			"\n\tk_stack_init"
155 			"\n\tk_stack_pop(K_FOREVER)"
156 			"\n\tk_stack_push");
157 	printf(sz_test_start_fmt);
158 
159 	stack_test_init();
160 
161 	t = BENCH_START();
162 
163 	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1,
164 			 0, INT_TO_POINTER(number_of_loops), NULL,
165 			 K_PRIO_COOP(3), 0, K_NO_WAIT);
166 	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_thread2,
167 			 (void *) &i, INT_TO_POINTER(number_of_loops), NULL,
168 			 K_PRIO_COOP(3), 0, K_NO_WAIT);
169 
170 	t = TIME_STAMP_DELTA_GET(t);
171 
172 	return_value += check_result(i, t);
173 
174 	/* test get/yield & put stack functions between co-op threads */
175 	fprintf(output_file, sz_test_case_fmt,
176 			"Stack #2");
177 	fprintf(output_file, sz_description,
178 			"\n\tk_stack_init"
179 			"\n\tk_stack_pop(K_FOREVER)"
180 			"\n\tk_stack_pop"
181 			"\n\tk_stack_push"
182 			"\n\tk_yield");
183 	printf(sz_test_start_fmt);
184 
185 	stack_test_init();
186 
187 	t = BENCH_START();
188 
189 	i = 0;
190 	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1,
191 			 0, INT_TO_POINTER(number_of_loops), NULL,
192 			 K_PRIO_COOP(3), 0, K_NO_WAIT);
193 	k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, stack_thread3,
194 			 (void *) &i, INT_TO_POINTER(number_of_loops), NULL,
195 			 K_PRIO_COOP(3), 0, K_NO_WAIT);
196 
197 	t = TIME_STAMP_DELTA_GET(t);
198 
199 	return_value += check_result(i, t);
200 
201 	/* test get wait & put stack functions across co-op and premptive
202 	 * threads
203 	 */
204 	fprintf(output_file, sz_test_case_fmt,
205 			"Stack #3");
206 	fprintf(output_file, sz_description,
207 			"\n\tk_stack_init"
208 			"\n\tk_stack_pop(K_FOREVER)"
209 			"\n\tk_stack_push"
210 			"\n\tk_stack_pop(K_FOREVER)"
211 			"\n\tk_stack_push");
212 	printf(sz_test_start_fmt);
213 
214 	stack_test_init();
215 
216 	t = BENCH_START();
217 
218 	k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, stack_thread1,
219 			 0, INT_TO_POINTER(number_of_loops), NULL,
220 			 K_PRIO_COOP(3), 0, K_NO_WAIT);
221 
222 	for (i = 0; i < number_of_loops / 2U; i++) {
223 		stack_data_t data;
224 
225 		data = 2 * i;
226 		k_stack_push(&stack_1, data);
227 		data = 2 * i + 1;
228 		k_stack_push(&stack_1, data);
229 
230 		k_stack_pop(&stack_2, &data, K_FOREVER);
231 		if (data != 2 * i + 1) {
232 			break;
233 		}
234 		k_stack_pop(&stack_2, &data, K_FOREVER);
235 		if (data != 2 * i) {
236 			break;
237 		}
238 	}
239 
240 	t = TIME_STAMP_DELTA_GET(t);
241 
242 	return_value += check_result(i * 2, t);
243 
244 	return return_value;
245 }
246