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