1 /* lifo.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_lifo lifo1;
12 struct k_lifo lifo2;
13
14 static struct k_fifo sync_fifo; /* for synchronization */
15
16 /**
17 *
18 * @brief Initialize LIFOs for the test
19 *
20 */
lifo_test_init(void)21 void lifo_test_init(void)
22 {
23 k_lifo_init(&lifo1);
24 k_lifo_init(&lifo2);
25 }
26
27
28 /**
29 *
30 * @brief Lifo test thread
31 *
32 * @param par1 Ignored parameter.
33 * @param par2 Number of test loops.
34 * @param par3 unused
35 *
36 */
lifo_thread1(void * par1,void * par2,void * par3)37 void lifo_thread1(void *par1, void *par2, void *par3)
38 {
39 int i;
40 intptr_t element_a[2];
41 intptr_t element_b[2];
42 intptr_t *pelement;
43 int num_loops = POINTER_TO_INT(par2);
44
45 ARG_UNUSED(par1);
46
47 for (i = 0; i < num_loops / 2; i++) {
48 pelement = k_lifo_get(&lifo1, K_FOREVER);
49 if (pelement[1] != 2 * i) {
50 break;
51 }
52 element_a[1] = 2 * i;
53 k_lifo_put(&lifo2, element_a);
54 pelement = k_lifo_get(&lifo1, K_FOREVER);
55 if (pelement[1] != 2 * i + 1) {
56 break;
57 }
58 element_b[1] = 2 * i + 1;
59 k_lifo_put(&lifo2, element_b);
60 }
61 /* wait till it is safe to end: */
62 k_fifo_get(&sync_fifo, K_FOREVER);
63 }
64
65
66 /**
67 *
68 * @brief Lifo test thread
69 *
70 * @param par1 Address of the counter.
71 * @param par2 Number of test cycles.
72 * @param par3 unused
73 *
74 */
lifo_thread2(void * par1,void * par2,void * par3)75 void lifo_thread2(void *par1, void *par2, void *par3)
76 {
77 int i;
78 intptr_t element[2];
79 intptr_t *pelement;
80 int *pcounter = par1;
81 int num_loops = POINTER_TO_INT(par2);
82
83 for (i = 0; i < num_loops; i++) {
84 element[1] = i;
85 k_lifo_put(&lifo1, element);
86 pelement = k_lifo_get(&lifo2, K_FOREVER);
87 if (pelement[1] != i) {
88 break;
89 }
90 (*pcounter)++;
91 }
92 /* wait till it is safe to end: */
93 k_fifo_get(&sync_fifo, K_FOREVER);
94 }
95
96 /**
97 *
98 * @brief Lifo test thread
99 *
100 * @param par1 Address of the counter.
101 * @param par2 Number of test loops.
102 * @param par3 unused
103 *
104 */
lifo_thread3(void * par1,void * par2,void * par3)105 void lifo_thread3(void *par1, void *par2, void *par3)
106 {
107 int i;
108 intptr_t element[2];
109 intptr_t *pelement;
110 int *pcounter = par1;
111 int num_loops = POINTER_TO_INT(par2);
112
113 for (i = 0; i < num_loops; i++) {
114 element[1] = i;
115 k_lifo_put(&lifo1, element);
116 while ((pelement = k_lifo_get(&lifo2, K_NO_WAIT)) == NULL) {
117 k_yield();
118 }
119 if (pelement[1] != i) {
120 break;
121 }
122 (*pcounter)++;
123 }
124 /* wait till it is safe to end: */
125 k_fifo_get(&sync_fifo, K_FOREVER);
126 }
127
128 /**
129 *
130 * @brief The main test entry
131 *
132 * @return 1 if success and 0 on failure
133 */
lifo_test(void)134 int lifo_test(void)
135 {
136 uint32_t t;
137 int i = 0;
138 int return_value = 0;
139 intptr_t element[2];
140 int j;
141
142 k_fifo_init(&sync_fifo);
143
144 /* test get/wait & put thread functions between co-op threads */
145 fprintf(output_file, sz_test_case_fmt,
146 "LIFO #1");
147 fprintf(output_file, sz_description,
148 "\n\tk_lifo_init"
149 "\n\tk_lifo_get(K_FOREVER)"
150 "\n\tk_lifo_put");
151 printf(sz_test_start_fmt);
152
153 lifo_test_init();
154
155 t = BENCH_START();
156
157 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
158 NULL, INT_TO_POINTER(number_of_loops), NULL,
159 K_PRIO_COOP(3), 0, K_NO_WAIT);
160
161 k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, lifo_thread2,
162 &i, INT_TO_POINTER(number_of_loops), NULL,
163 K_PRIO_COOP(3), 0, K_NO_WAIT);
164
165 t = TIME_STAMP_DELTA_GET(t);
166
167 return_value += check_result(i, t);
168
169 /* threads have done their job, they can stop now safely: */
170 for (j = 0; j < 2; j++) {
171 k_fifo_put(&sync_fifo, element);
172 }
173
174 /* test get/yield & put thread functions between co-op threads */
175 fprintf(output_file, sz_test_case_fmt,
176 "LIFO #2");
177 fprintf(output_file, sz_description,
178 "\n\tk_lifo_init"
179 "\n\tk_lifo_get(K_FOREVER)"
180 "\n\tk_lifo_get(K_NO_WAIT)"
181 "\n\tk_lifo_put"
182 "\n\tk_yield");
183 printf(sz_test_start_fmt);
184
185 lifo_test_init();
186
187 t = BENCH_START();
188
189 i = 0;
190
191 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
192 NULL, INT_TO_POINTER(number_of_loops), NULL,
193 K_PRIO_COOP(3), 0, K_NO_WAIT);
194
195 k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, lifo_thread3,
196 &i, INT_TO_POINTER(number_of_loops), NULL,
197 K_PRIO_COOP(3), 0, K_NO_WAIT);
198
199 t = TIME_STAMP_DELTA_GET(t);
200
201 return_value += check_result(i, t);
202
203 /* threads have done their job, they can stop now safely: */
204 for (j = 0; j < 2; j++) {
205 k_fifo_put(&sync_fifo, element);
206 }
207
208 /* test get wait & put functions between co-op and preemptive threads */
209 fprintf(output_file, sz_test_case_fmt,
210 "LIFO #3");
211 fprintf(output_file, sz_description,
212 "\n\tk_lifo_init"
213 "\n\tk_lifo_get(K_FOREVER)"
214 "\n\tk_lifo_put"
215 "\n\tk_lifo_get(K_FOREVER)"
216 "\n\tk_lifo_put");
217 printf(sz_test_start_fmt);
218
219 lifo_test_init();
220
221 t = BENCH_START();
222
223 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, lifo_thread1,
224 NULL, INT_TO_POINTER(number_of_loops), NULL,
225 K_PRIO_COOP(3), 0, K_NO_WAIT);
226 for (i = 0; i < number_of_loops / 2U; i++) {
227 intptr_t more_element[2];
228 intptr_t *pelement;
229
230 more_element[1] = 2 * i;
231 k_lifo_put(&lifo1, more_element);
232 more_element[1] = 2 * i + 1;
233 k_lifo_put(&lifo1, more_element);
234
235 pelement = k_lifo_get(&lifo2, K_FOREVER);
236 if (pelement[1] != 2 * i + 1) {
237 break;
238 }
239 pelement = k_lifo_get(&lifo2, K_FOREVER);
240 if (pelement[1] != 2 * i) {
241 break;
242 }
243 }
244
245 t = TIME_STAMP_DELTA_GET(t);
246
247 return_value += check_result(i * 2, t);
248
249 /* threads have done their job, they can stop now safely: */
250 for (j = 0; j < 2; j++) {
251 k_fifo_put(&sync_fifo, element);
252 }
253
254 return return_value;
255 }
256