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