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