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