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