1 /* fifo.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
10 #include "syskernel.h"
11
12 struct k_fifo fifo1;
13 struct k_fifo fifo2;
14
15 static struct k_fifo sync_fifo; /* for synchronization */
16
17
18 /**
19 *
20 * @brief Initialize FIFOs for the test
21 *
22 */
fifo_test_init(void)23 void fifo_test_init(void)
24 {
25 k_fifo_init(&fifo1);
26 k_fifo_init(&fifo2);
27 }
28
29
30 /**
31 *
32 * @brief Fifo test thread
33 *
34 * @param par1 Ignored parameter.
35 * @param par2 Number of test loops.
36 * @param par3 unused
37 *
38 */
fifo_thread1(void * par1,void * par2,void * par3)39 void fifo_thread1(void *par1, void *par2, void *par3)
40 {
41 int i;
42 intptr_t element[2];
43 intptr_t *pelement;
44 int num_loops = POINTER_TO_INT(par2);
45
46 ARG_UNUSED(par1);
47 ARG_UNUSED(par3);
48 for (i = 0; i < num_loops; i++) {
49 pelement = k_fifo_get(&fifo1, K_FOREVER);
50 if (pelement[1] != i) {
51 break;
52 }
53 element[1] = i;
54 k_fifo_put(&fifo2, element);
55 }
56 /* wait till it is safe to end: */
57 k_fifo_get(&sync_fifo, K_FOREVER);
58 }
59
60
61 /**
62 *
63 * @brief Fifo test thread
64 *
65 * @param par1 Address of the counter.
66 * @param par2 Number of test cycles.
67 * @param par3 unused
68 *
69 */
fifo_thread2(void * par1,void * par2,void * par3)70 void fifo_thread2(void *par1, void *par2, void *par3)
71 {
72 int i;
73 intptr_t element[2];
74 intptr_t *pelement;
75 int *pcounter = par1;
76 int num_loops = POINTER_TO_INT(par2);
77
78 ARG_UNUSED(par3);
79
80 for (i = 0; i < num_loops; i++) {
81 element[1] = i;
82 k_fifo_put(&fifo1, element);
83 pelement = k_fifo_get(&fifo2, K_FOREVER);
84 if (pelement[1] != i) {
85 break;
86 }
87 (*pcounter)++;
88 }
89 /* wait till it is safe to end: */
90 k_fifo_get(&sync_fifo, K_FOREVER);
91 }
92
93
94 /**
95 *
96 * @brief Fifo test thread
97 *
98 * @param par1 Address of the counter.
99 * @param par2 Number of test cycles.
100 * @param par3 unused
101 *
102 */
fifo_thread3(void * par1,void * par2,void * par3)103 void fifo_thread3(void *par1, void *par2, void *par3)
104 {
105 int i;
106 intptr_t element[2];
107 intptr_t *pelement;
108 int *pcounter = par1;
109 int num_loops = POINTER_TO_INT(par2);
110
111 ARG_UNUSED(par3);
112
113 for (i = 0; i < num_loops; i++) {
114 element[1] = i;
115 k_fifo_put(&fifo1, element);
116 while ((pelement = k_fifo_get(&fifo2, 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 *
131 * @brief The main test entry
132 *
133 * @return 1 if success and 0 on failure
134 */
fifo_test(void)135 int fifo_test(void)
136 {
137 uint32_t t;
138 int i = 0;
139 int return_value = 0;
140 intptr_t element[2];
141 int j;
142
143 k_fifo_init(&sync_fifo);
144
145 /* test get wait & put thread functions between co-op threads */
146 fprintf(output_file, sz_test_case_fmt,
147 "FIFO #1");
148 fprintf(output_file, sz_description,
149 "\n\tk_fifo_init"
150 "\n\tk_fifo_get(K_FOREVER)"
151 "\n\tk_fifo_put");
152 printf(sz_test_start_fmt);
153
154 fifo_test_init();
155
156 t = BENCH_START();
157
158 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
159 NULL, INT_TO_POINTER(number_of_loops), NULL,
160 K_PRIO_COOP(3), 0, K_NO_WAIT);
161 k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, fifo_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 "FIFO #2");
177 fprintf(output_file, sz_description,
178 "\n\tk_fifo_init"
179 "\n\tk_fifo_get(K_FOREVER)"
180 "\n\tk_fifo_get(K_NO_WAIT)"
181 "\n\tk_fifo_put"
182 "\n\tk_yield");
183 printf(sz_test_start_fmt);
184
185 fifo_test_init();
186
187 t = BENCH_START();
188
189 i = 0;
190 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
191 NULL, 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, fifo_thread3,
194 &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 /* threads have done their job, they can stop now safely: */
202 for (j = 0; j < 2; j++) {
203 k_fifo_put(&sync_fifo, element);
204 }
205
206 /* test get wait & put functions between co-op and preemptive threads */
207 fprintf(output_file, sz_test_case_fmt,
208 "FIFO #3");
209 fprintf(output_file, sz_description,
210 "\n\tk_fifo_init"
211 "\n\tk_fifo_get(K_FOREVER)"
212 "\n\tk_fifo_put"
213 "\n\tk_fifo_get(K_FOREVER)"
214 "\n\tk_fifo_put");
215 printf(sz_test_start_fmt);
216
217 fifo_test_init();
218
219 t = BENCH_START();
220
221 k_thread_create(&thread_data1, thread_stack1, STACK_SIZE, fifo_thread1,
222 NULL, INT_TO_POINTER(number_of_loops / 2U), NULL,
223 K_PRIO_COOP(3), 0, K_NO_WAIT);
224 k_thread_create(&thread_data2, thread_stack2, STACK_SIZE, fifo_thread1,
225 NULL, INT_TO_POINTER(number_of_loops / 2U), NULL,
226 K_PRIO_COOP(3), 0, K_NO_WAIT);
227 for (i = 0; i < number_of_loops / 2U; i++) {
228 intptr_t more_element[2];
229 intptr_t *pelement;
230
231 more_element[1] = i;
232 k_fifo_put(&fifo1, more_element);
233 more_element[1] = i;
234 k_fifo_put(&fifo1, more_element);
235
236 pelement = k_fifo_get(&fifo2, K_FOREVER);
237 if (pelement[1] != i) {
238 break;
239 }
240 pelement = k_fifo_get(&fifo2, K_FOREVER);
241 if (pelement[1] != i) {
242 break;
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