xref: /dpdk/app/test/test_lcore_var.c (revision b0faa8330bfdc919c6591850e883b57304bd0fbe)
1*b0faa833SMattias Rönnblom /* SPDX-License-Identifier: BSD-3-Clause
2*b0faa833SMattias Rönnblom  * Copyright(c) 2024 Ericsson AB
3*b0faa833SMattias Rönnblom  */
4*b0faa833SMattias Rönnblom 
5*b0faa833SMattias Rönnblom #include <inttypes.h>
6*b0faa833SMattias Rönnblom #include <stdio.h>
7*b0faa833SMattias Rönnblom #include <string.h>
8*b0faa833SMattias Rönnblom 
9*b0faa833SMattias Rönnblom #include <rte_launch.h>
10*b0faa833SMattias Rönnblom #include <rte_lcore_var.h>
11*b0faa833SMattias Rönnblom #include <rte_random.h>
12*b0faa833SMattias Rönnblom 
13*b0faa833SMattias Rönnblom #include "test.h"
14*b0faa833SMattias Rönnblom 
15*b0faa833SMattias Rönnblom #define MIN_LCORES 2
16*b0faa833SMattias Rönnblom 
17*b0faa833SMattias Rönnblom RTE_LCORE_VAR_HANDLE(int, test_int);
18*b0faa833SMattias Rönnblom RTE_LCORE_VAR_HANDLE(char, test_char);
19*b0faa833SMattias Rönnblom RTE_LCORE_VAR_HANDLE(long, test_long_sized);
20*b0faa833SMattias Rönnblom RTE_LCORE_VAR_HANDLE(short, test_short);
21*b0faa833SMattias Rönnblom RTE_LCORE_VAR_HANDLE(long, test_long_sized_aligned);
22*b0faa833SMattias Rönnblom 
23*b0faa833SMattias Rönnblom struct int_checker_state {
24*b0faa833SMattias Rönnblom 	int old_value;
25*b0faa833SMattias Rönnblom 	int new_value;
26*b0faa833SMattias Rönnblom 	bool success;
27*b0faa833SMattias Rönnblom };
28*b0faa833SMattias Rönnblom 
29*b0faa833SMattias Rönnblom static void
30*b0faa833SMattias Rönnblom rand_blk(void *blk, size_t size)
31*b0faa833SMattias Rönnblom {
32*b0faa833SMattias Rönnblom 	size_t i;
33*b0faa833SMattias Rönnblom 
34*b0faa833SMattias Rönnblom 	for (i = 0; i < size; i++)
35*b0faa833SMattias Rönnblom 		((unsigned char *)blk)[i] = (unsigned char)rte_rand();
36*b0faa833SMattias Rönnblom }
37*b0faa833SMattias Rönnblom 
38*b0faa833SMattias Rönnblom static bool
39*b0faa833SMattias Rönnblom is_ptr_aligned(const void *ptr, size_t align)
40*b0faa833SMattias Rönnblom {
41*b0faa833SMattias Rönnblom 	return ptr != NULL ? (uintptr_t)ptr % align == 0 : false;
42*b0faa833SMattias Rönnblom }
43*b0faa833SMattias Rönnblom 
44*b0faa833SMattias Rönnblom static int
45*b0faa833SMattias Rönnblom check_int(void *arg)
46*b0faa833SMattias Rönnblom {
47*b0faa833SMattias Rönnblom 	struct int_checker_state *state = arg;
48*b0faa833SMattias Rönnblom 
49*b0faa833SMattias Rönnblom 	int *ptr = RTE_LCORE_VAR(test_int);
50*b0faa833SMattias Rönnblom 
51*b0faa833SMattias Rönnblom 	bool naturally_aligned = is_ptr_aligned(ptr, sizeof(int));
52*b0faa833SMattias Rönnblom 
53*b0faa833SMattias Rönnblom 	bool equal = *(RTE_LCORE_VAR(test_int)) == state->old_value;
54*b0faa833SMattias Rönnblom 
55*b0faa833SMattias Rönnblom 	state->success = equal && naturally_aligned;
56*b0faa833SMattias Rönnblom 
57*b0faa833SMattias Rönnblom 	*ptr = state->new_value;
58*b0faa833SMattias Rönnblom 
59*b0faa833SMattias Rönnblom 	return 0;
60*b0faa833SMattias Rönnblom }
61*b0faa833SMattias Rönnblom 
62*b0faa833SMattias Rönnblom RTE_LCORE_VAR_INIT(test_int);
63*b0faa833SMattias Rönnblom RTE_LCORE_VAR_INIT(test_char);
64*b0faa833SMattias Rönnblom RTE_LCORE_VAR_INIT_SIZE(test_long_sized, 32);
65*b0faa833SMattias Rönnblom RTE_LCORE_VAR_INIT(test_short);
66*b0faa833SMattias Rönnblom RTE_LCORE_VAR_INIT_SIZE_ALIGN(test_long_sized_aligned, sizeof(long), RTE_CACHE_LINE_SIZE);
67*b0faa833SMattias Rönnblom 
68*b0faa833SMattias Rönnblom static int
69*b0faa833SMattias Rönnblom test_int_lvar(void)
70*b0faa833SMattias Rönnblom {
71*b0faa833SMattias Rönnblom 	unsigned int lcore_id;
72*b0faa833SMattias Rönnblom 
73*b0faa833SMattias Rönnblom 	struct int_checker_state states[RTE_MAX_LCORE] = {};
74*b0faa833SMattias Rönnblom 
75*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
76*b0faa833SMattias Rönnblom 		struct int_checker_state *state = &states[lcore_id];
77*b0faa833SMattias Rönnblom 
78*b0faa833SMattias Rönnblom 		state->old_value = (int)rte_rand();
79*b0faa833SMattias Rönnblom 		state->new_value = (int)rte_rand();
80*b0faa833SMattias Rönnblom 
81*b0faa833SMattias Rönnblom 		*RTE_LCORE_VAR_LCORE(lcore_id, test_int) = state->old_value;
82*b0faa833SMattias Rönnblom 	}
83*b0faa833SMattias Rönnblom 
84*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id)
85*b0faa833SMattias Rönnblom 		rte_eal_remote_launch(check_int, &states[lcore_id], lcore_id);
86*b0faa833SMattias Rönnblom 
87*b0faa833SMattias Rönnblom 	rte_eal_mp_wait_lcore();
88*b0faa833SMattias Rönnblom 
89*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
90*b0faa833SMattias Rönnblom 		struct int_checker_state *state = &states[lcore_id];
91*b0faa833SMattias Rönnblom 		int value;
92*b0faa833SMattias Rönnblom 
93*b0faa833SMattias Rönnblom 		TEST_ASSERT(state->success,
94*b0faa833SMattias Rönnblom 				"Unexpected value encountered on lcore %d", lcore_id);
95*b0faa833SMattias Rönnblom 
96*b0faa833SMattias Rönnblom 		value = *RTE_LCORE_VAR_LCORE(lcore_id, test_int);
97*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(state->new_value, value,
98*b0faa833SMattias Rönnblom 				"Lcore %d failed to update int", lcore_id);
99*b0faa833SMattias Rönnblom 	}
100*b0faa833SMattias Rönnblom 
101*b0faa833SMattias Rönnblom 	/* take the opportunity to test the foreach macro */
102*b0faa833SMattias Rönnblom 	int *v;
103*b0faa833SMattias Rönnblom 	unsigned int i = 0;
104*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_FOREACH(lcore_id, v, test_int) {
105*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(i, lcore_id,
106*b0faa833SMattias Rönnblom 				"Encountered lcore id %d while expecting %d during iteration",
107*b0faa833SMattias Rönnblom 				lcore_id, i);
108*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(states[lcore_id].new_value, *v,
109*b0faa833SMattias Rönnblom 				"Unexpected value on lcore %d during iteration", lcore_id);
110*b0faa833SMattias Rönnblom 		i++;
111*b0faa833SMattias Rönnblom 	}
112*b0faa833SMattias Rönnblom 
113*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
114*b0faa833SMattias Rönnblom }
115*b0faa833SMattias Rönnblom 
116*b0faa833SMattias Rönnblom static int
117*b0faa833SMattias Rönnblom test_sized_alignment(void)
118*b0faa833SMattias Rönnblom {
119*b0faa833SMattias Rönnblom 	unsigned int lcore_id;
120*b0faa833SMattias Rönnblom 	long *v;
121*b0faa833SMattias Rönnblom 
122*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_FOREACH(lcore_id, v, test_long_sized) {
123*b0faa833SMattias Rönnblom 		TEST_ASSERT(is_ptr_aligned(v, alignof(long)), "Type-derived alignment failed");
124*b0faa833SMattias Rönnblom 	}
125*b0faa833SMattias Rönnblom 
126*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_FOREACH(lcore_id, v, test_long_sized_aligned) {
127*b0faa833SMattias Rönnblom 		TEST_ASSERT(is_ptr_aligned(v, RTE_CACHE_LINE_SIZE), "Explicit alignment failed");
128*b0faa833SMattias Rönnblom 	}
129*b0faa833SMattias Rönnblom 
130*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
131*b0faa833SMattias Rönnblom }
132*b0faa833SMattias Rönnblom 
133*b0faa833SMattias Rönnblom /* private, larger, struct */
134*b0faa833SMattias Rönnblom #define TEST_STRUCT_DATA_SIZE 1234
135*b0faa833SMattias Rönnblom 
136*b0faa833SMattias Rönnblom struct test_struct {
137*b0faa833SMattias Rönnblom 	uint8_t data[TEST_STRUCT_DATA_SIZE];
138*b0faa833SMattias Rönnblom };
139*b0faa833SMattias Rönnblom 
140*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(char, before_struct);
141*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(struct test_struct, test_struct);
142*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(char, after_struct);
143*b0faa833SMattias Rönnblom 
144*b0faa833SMattias Rönnblom struct struct_checker_state {
145*b0faa833SMattias Rönnblom 	struct test_struct old_value;
146*b0faa833SMattias Rönnblom 	struct test_struct new_value;
147*b0faa833SMattias Rönnblom 	bool success;
148*b0faa833SMattias Rönnblom };
149*b0faa833SMattias Rönnblom 
150*b0faa833SMattias Rönnblom static int check_struct(void *arg)
151*b0faa833SMattias Rönnblom {
152*b0faa833SMattias Rönnblom 	struct struct_checker_state *state = arg;
153*b0faa833SMattias Rönnblom 
154*b0faa833SMattias Rönnblom 	struct test_struct *lcore_struct = RTE_LCORE_VAR(test_struct);
155*b0faa833SMattias Rönnblom 
156*b0faa833SMattias Rönnblom 	bool properly_aligned = is_ptr_aligned(test_struct, alignof(struct test_struct));
157*b0faa833SMattias Rönnblom 
158*b0faa833SMattias Rönnblom 	bool equal = memcmp(lcore_struct->data, state->old_value.data, TEST_STRUCT_DATA_SIZE) == 0;
159*b0faa833SMattias Rönnblom 
160*b0faa833SMattias Rönnblom 	state->success = equal && properly_aligned;
161*b0faa833SMattias Rönnblom 
162*b0faa833SMattias Rönnblom 	memcpy(lcore_struct->data, state->new_value.data, TEST_STRUCT_DATA_SIZE);
163*b0faa833SMattias Rönnblom 
164*b0faa833SMattias Rönnblom 	return 0;
165*b0faa833SMattias Rönnblom }
166*b0faa833SMattias Rönnblom 
167*b0faa833SMattias Rönnblom static int
168*b0faa833SMattias Rönnblom test_struct_lvar(void)
169*b0faa833SMattias Rönnblom {
170*b0faa833SMattias Rönnblom 	unsigned int lcore_id;
171*b0faa833SMattias Rönnblom 
172*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(before_struct);
173*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(test_struct);
174*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(after_struct);
175*b0faa833SMattias Rönnblom 
176*b0faa833SMattias Rönnblom 	struct struct_checker_state states[RTE_MAX_LCORE];
177*b0faa833SMattias Rönnblom 
178*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
179*b0faa833SMattias Rönnblom 		struct struct_checker_state *state = &states[lcore_id];
180*b0faa833SMattias Rönnblom 
181*b0faa833SMattias Rönnblom 		rand_blk(state->old_value.data, TEST_STRUCT_DATA_SIZE);
182*b0faa833SMattias Rönnblom 		rand_blk(state->new_value.data, TEST_STRUCT_DATA_SIZE);
183*b0faa833SMattias Rönnblom 
184*b0faa833SMattias Rönnblom 		memcpy(RTE_LCORE_VAR_LCORE(lcore_id, test_struct)->data,
185*b0faa833SMattias Rönnblom 				state->old_value.data, TEST_STRUCT_DATA_SIZE);
186*b0faa833SMattias Rönnblom 	}
187*b0faa833SMattias Rönnblom 
188*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id)
189*b0faa833SMattias Rönnblom 		rte_eal_remote_launch(check_struct, &states[lcore_id], lcore_id);
190*b0faa833SMattias Rönnblom 
191*b0faa833SMattias Rönnblom 	rte_eal_mp_wait_lcore();
192*b0faa833SMattias Rönnblom 
193*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
194*b0faa833SMattias Rönnblom 		struct struct_checker_state *state = &states[lcore_id];
195*b0faa833SMattias Rönnblom 		struct test_struct *lstruct = RTE_LCORE_VAR_LCORE(lcore_id, test_struct);
196*b0faa833SMattias Rönnblom 
197*b0faa833SMattias Rönnblom 		TEST_ASSERT(state->success, "Unexpected value encountered on lcore %d", lcore_id);
198*b0faa833SMattias Rönnblom 
199*b0faa833SMattias Rönnblom 		bool equal = memcmp(lstruct->data, state->new_value.data,
200*b0faa833SMattias Rönnblom 				TEST_STRUCT_DATA_SIZE) == 0;
201*b0faa833SMattias Rönnblom 
202*b0faa833SMattias Rönnblom 		TEST_ASSERT(equal, "Lcore %d failed to update struct", lcore_id);
203*b0faa833SMattias Rönnblom 	}
204*b0faa833SMattias Rönnblom 
205*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
206*b0faa833SMattias Rönnblom 		char before = *RTE_LCORE_VAR_LCORE(lcore_id, before_struct);
207*b0faa833SMattias Rönnblom 		char after = *RTE_LCORE_VAR_LCORE(lcore_id, after_struct);
208*b0faa833SMattias Rönnblom 
209*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(before, 0,
210*b0faa833SMattias Rönnblom 				"Lcore variable before test struct was modified on lcore %d",
211*b0faa833SMattias Rönnblom 				lcore_id);
212*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(after, 0,
213*b0faa833SMattias Rönnblom 				"Lcore variable after test struct was modified on lcore %d",
214*b0faa833SMattias Rönnblom 				lcore_id);
215*b0faa833SMattias Rönnblom 	}
216*b0faa833SMattias Rönnblom 
217*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
218*b0faa833SMattias Rönnblom }
219*b0faa833SMattias Rönnblom 
220*b0faa833SMattias Rönnblom #define TEST_ARRAY_SIZE 99
221*b0faa833SMattias Rönnblom 
222*b0faa833SMattias Rönnblom typedef uint16_t test_array_t[TEST_ARRAY_SIZE];
223*b0faa833SMattias Rönnblom 
224*b0faa833SMattias Rönnblom static void test_array_init_rand(test_array_t a)
225*b0faa833SMattias Rönnblom {
226*b0faa833SMattias Rönnblom 	size_t i;
227*b0faa833SMattias Rönnblom 	for (i = 0; i < TEST_ARRAY_SIZE; i++)
228*b0faa833SMattias Rönnblom 		a[i] = (uint16_t)rte_rand();
229*b0faa833SMattias Rönnblom }
230*b0faa833SMattias Rönnblom 
231*b0faa833SMattias Rönnblom static bool test_array_equal(test_array_t a, test_array_t b)
232*b0faa833SMattias Rönnblom {
233*b0faa833SMattias Rönnblom 	size_t i;
234*b0faa833SMattias Rönnblom 	for (i = 0; i < TEST_ARRAY_SIZE; i++) {
235*b0faa833SMattias Rönnblom 		if (a[i] != b[i])
236*b0faa833SMattias Rönnblom 			return false;
237*b0faa833SMattias Rönnblom 	}
238*b0faa833SMattias Rönnblom 	return true;
239*b0faa833SMattias Rönnblom }
240*b0faa833SMattias Rönnblom 
241*b0faa833SMattias Rönnblom static void test_array_copy(test_array_t dst, const test_array_t src)
242*b0faa833SMattias Rönnblom {
243*b0faa833SMattias Rönnblom 	size_t i;
244*b0faa833SMattias Rönnblom 	for (i = 0; i < TEST_ARRAY_SIZE; i++)
245*b0faa833SMattias Rönnblom 		dst[i] = src[i];
246*b0faa833SMattias Rönnblom }
247*b0faa833SMattias Rönnblom 
248*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(char, before_array);
249*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(test_array_t, test_array);
250*b0faa833SMattias Rönnblom static RTE_LCORE_VAR_HANDLE(char, after_array);
251*b0faa833SMattias Rönnblom 
252*b0faa833SMattias Rönnblom struct array_checker_state {
253*b0faa833SMattias Rönnblom 	test_array_t old_value;
254*b0faa833SMattias Rönnblom 	test_array_t new_value;
255*b0faa833SMattias Rönnblom 	bool success;
256*b0faa833SMattias Rönnblom };
257*b0faa833SMattias Rönnblom 
258*b0faa833SMattias Rönnblom static int check_array(void *arg)
259*b0faa833SMattias Rönnblom {
260*b0faa833SMattias Rönnblom 	struct array_checker_state *state = arg;
261*b0faa833SMattias Rönnblom 
262*b0faa833SMattias Rönnblom 	test_array_t *lcore_array = RTE_LCORE_VAR(test_array);
263*b0faa833SMattias Rönnblom 
264*b0faa833SMattias Rönnblom 	bool properly_aligned = is_ptr_aligned(lcore_array, alignof(test_array_t));
265*b0faa833SMattias Rönnblom 
266*b0faa833SMattias Rönnblom 	bool equal = test_array_equal(*lcore_array, state->old_value);
267*b0faa833SMattias Rönnblom 
268*b0faa833SMattias Rönnblom 	state->success = equal && properly_aligned;
269*b0faa833SMattias Rönnblom 
270*b0faa833SMattias Rönnblom 	test_array_copy(*lcore_array, state->new_value);
271*b0faa833SMattias Rönnblom 
272*b0faa833SMattias Rönnblom 	return 0;
273*b0faa833SMattias Rönnblom }
274*b0faa833SMattias Rönnblom 
275*b0faa833SMattias Rönnblom static int
276*b0faa833SMattias Rönnblom test_array_lvar(void)
277*b0faa833SMattias Rönnblom {
278*b0faa833SMattias Rönnblom 	unsigned int lcore_id;
279*b0faa833SMattias Rönnblom 
280*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(before_array);
281*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(test_array);
282*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC(after_array);
283*b0faa833SMattias Rönnblom 
284*b0faa833SMattias Rönnblom 	struct array_checker_state states[RTE_MAX_LCORE];
285*b0faa833SMattias Rönnblom 
286*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
287*b0faa833SMattias Rönnblom 		struct array_checker_state *state = &states[lcore_id];
288*b0faa833SMattias Rönnblom 
289*b0faa833SMattias Rönnblom 		test_array_init_rand(state->new_value);
290*b0faa833SMattias Rönnblom 		test_array_init_rand(state->old_value);
291*b0faa833SMattias Rönnblom 
292*b0faa833SMattias Rönnblom 		test_array_copy(*RTE_LCORE_VAR_LCORE(lcore_id, test_array), state->old_value);
293*b0faa833SMattias Rönnblom 	}
294*b0faa833SMattias Rönnblom 
295*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id)
296*b0faa833SMattias Rönnblom 		rte_eal_remote_launch(check_array, &states[lcore_id], lcore_id);
297*b0faa833SMattias Rönnblom 
298*b0faa833SMattias Rönnblom 	rte_eal_mp_wait_lcore();
299*b0faa833SMattias Rönnblom 
300*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
301*b0faa833SMattias Rönnblom 		struct array_checker_state *state = &states[lcore_id];
302*b0faa833SMattias Rönnblom 		test_array_t *larray = RTE_LCORE_VAR_LCORE(lcore_id, test_array);
303*b0faa833SMattias Rönnblom 
304*b0faa833SMattias Rönnblom 		TEST_ASSERT(state->success, "Unexpected value encountered on lcore %d", lcore_id);
305*b0faa833SMattias Rönnblom 
306*b0faa833SMattias Rönnblom 		bool equal = test_array_equal(*larray, state->new_value);
307*b0faa833SMattias Rönnblom 
308*b0faa833SMattias Rönnblom 		TEST_ASSERT(equal, "Lcore %d failed to update array", lcore_id);
309*b0faa833SMattias Rönnblom 	}
310*b0faa833SMattias Rönnblom 
311*b0faa833SMattias Rönnblom 	RTE_LCORE_FOREACH_WORKER(lcore_id) {
312*b0faa833SMattias Rönnblom 		char before = *RTE_LCORE_VAR_LCORE(lcore_id, before_array);
313*b0faa833SMattias Rönnblom 		char after = *RTE_LCORE_VAR_LCORE(lcore_id, after_array);
314*b0faa833SMattias Rönnblom 
315*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(before, 0,
316*b0faa833SMattias Rönnblom 				"Lcore variable before test array was modified on lcore %d",
317*b0faa833SMattias Rönnblom 				lcore_id);
318*b0faa833SMattias Rönnblom 		TEST_ASSERT_EQUAL(after, 0,
319*b0faa833SMattias Rönnblom 				"Lcore variable after test array was modified on lcore %d",
320*b0faa833SMattias Rönnblom 				lcore_id);
321*b0faa833SMattias Rönnblom 	}
322*b0faa833SMattias Rönnblom 
323*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
324*b0faa833SMattias Rönnblom }
325*b0faa833SMattias Rönnblom 
326*b0faa833SMattias Rönnblom #define MANY_LVARS (2 * RTE_MAX_LCORE_VAR / sizeof(uint32_t))
327*b0faa833SMattias Rönnblom 
328*b0faa833SMattias Rönnblom static int
329*b0faa833SMattias Rönnblom test_many_lvars(void)
330*b0faa833SMattias Rönnblom {
331*b0faa833SMattias Rönnblom 	uint32_t **handlers = malloc(sizeof(uint32_t *) * MANY_LVARS);
332*b0faa833SMattias Rönnblom 	unsigned int i;
333*b0faa833SMattias Rönnblom 
334*b0faa833SMattias Rönnblom 	TEST_ASSERT(handlers != NULL, "Unable to allocate memory");
335*b0faa833SMattias Rönnblom 
336*b0faa833SMattias Rönnblom 	for (i = 0; i < MANY_LVARS; i++) {
337*b0faa833SMattias Rönnblom 		unsigned int lcore_id;
338*b0faa833SMattias Rönnblom 
339*b0faa833SMattias Rönnblom 		RTE_LCORE_VAR_ALLOC(handlers[i]);
340*b0faa833SMattias Rönnblom 
341*b0faa833SMattias Rönnblom 		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
342*b0faa833SMattias Rönnblom 			uint32_t *v = RTE_LCORE_VAR_LCORE(lcore_id, handlers[i]);
343*b0faa833SMattias Rönnblom 			*v = (uint32_t)(i * lcore_id);
344*b0faa833SMattias Rönnblom 		}
345*b0faa833SMattias Rönnblom 	}
346*b0faa833SMattias Rönnblom 
347*b0faa833SMattias Rönnblom 	for (i = 0; i < MANY_LVARS; i++) {
348*b0faa833SMattias Rönnblom 		unsigned int lcore_id;
349*b0faa833SMattias Rönnblom 
350*b0faa833SMattias Rönnblom 		for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
351*b0faa833SMattias Rönnblom 			uint32_t v = *RTE_LCORE_VAR_LCORE(lcore_id, handlers[i]);
352*b0faa833SMattias Rönnblom 			TEST_ASSERT_EQUAL((uint32_t)(i * lcore_id), v,
353*b0faa833SMattias Rönnblom 					"Unexpected lcore variable value on lcore %d",
354*b0faa833SMattias Rönnblom 					lcore_id);
355*b0faa833SMattias Rönnblom 		}
356*b0faa833SMattias Rönnblom 	}
357*b0faa833SMattias Rönnblom 
358*b0faa833SMattias Rönnblom 	free(handlers);
359*b0faa833SMattias Rönnblom 
360*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
361*b0faa833SMattias Rönnblom }
362*b0faa833SMattias Rönnblom 
363*b0faa833SMattias Rönnblom static int
364*b0faa833SMattias Rönnblom test_large_lvar(void)
365*b0faa833SMattias Rönnblom {
366*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_HANDLE(unsigned char, large);
367*b0faa833SMattias Rönnblom 	unsigned int lcore_id;
368*b0faa833SMattias Rönnblom 
369*b0faa833SMattias Rönnblom 	RTE_LCORE_VAR_ALLOC_SIZE(large, RTE_MAX_LCORE_VAR);
370*b0faa833SMattias Rönnblom 
371*b0faa833SMattias Rönnblom 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
372*b0faa833SMattias Rönnblom 		unsigned char *ptr = RTE_LCORE_VAR_LCORE(lcore_id, large);
373*b0faa833SMattias Rönnblom 
374*b0faa833SMattias Rönnblom 		memset(ptr, (unsigned char)lcore_id, RTE_MAX_LCORE_VAR);
375*b0faa833SMattias Rönnblom 	}
376*b0faa833SMattias Rönnblom 
377*b0faa833SMattias Rönnblom 	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id++) {
378*b0faa833SMattias Rönnblom 		unsigned char *ptr = RTE_LCORE_VAR_LCORE(lcore_id, large);
379*b0faa833SMattias Rönnblom 		size_t i;
380*b0faa833SMattias Rönnblom 
381*b0faa833SMattias Rönnblom 		for (i = 0; i < RTE_MAX_LCORE_VAR; i++)
382*b0faa833SMattias Rönnblom 			TEST_ASSERT_EQUAL(ptr[i], (unsigned char)lcore_id,
383*b0faa833SMattias Rönnblom 					"Large lcore variable value is corrupted on lcore %d.",
384*b0faa833SMattias Rönnblom 					lcore_id);
385*b0faa833SMattias Rönnblom 	}
386*b0faa833SMattias Rönnblom 
387*b0faa833SMattias Rönnblom 	return TEST_SUCCESS;
388*b0faa833SMattias Rönnblom }
389*b0faa833SMattias Rönnblom 
390*b0faa833SMattias Rönnblom static struct unit_test_suite lcore_var_testsuite = {
391*b0faa833SMattias Rönnblom 	.suite_name = "lcore variable autotest",
392*b0faa833SMattias Rönnblom 	.unit_test_cases = {
393*b0faa833SMattias Rönnblom 		TEST_CASE(test_int_lvar),
394*b0faa833SMattias Rönnblom 		TEST_CASE(test_sized_alignment),
395*b0faa833SMattias Rönnblom 		TEST_CASE(test_struct_lvar),
396*b0faa833SMattias Rönnblom 		TEST_CASE(test_array_lvar),
397*b0faa833SMattias Rönnblom 		TEST_CASE(test_many_lvars),
398*b0faa833SMattias Rönnblom 		TEST_CASE(test_large_lvar),
399*b0faa833SMattias Rönnblom 		TEST_CASES_END()
400*b0faa833SMattias Rönnblom 	},
401*b0faa833SMattias Rönnblom };
402*b0faa833SMattias Rönnblom 
403*b0faa833SMattias Rönnblom static int test_lcore_var(void)
404*b0faa833SMattias Rönnblom {
405*b0faa833SMattias Rönnblom 	if (rte_lcore_count() < MIN_LCORES) {
406*b0faa833SMattias Rönnblom 		printf("Not enough cores for lcore_var_autotest; expecting at least %d.\n",
407*b0faa833SMattias Rönnblom 				MIN_LCORES);
408*b0faa833SMattias Rönnblom 		return TEST_SKIPPED;
409*b0faa833SMattias Rönnblom 	}
410*b0faa833SMattias Rönnblom 
411*b0faa833SMattias Rönnblom 	return unit_test_suite_runner(&lcore_var_testsuite);
412*b0faa833SMattias Rönnblom }
413*b0faa833SMattias Rönnblom 
414*b0faa833SMattias Rönnblom REGISTER_FAST_TEST(lcore_var_autotest, true, false, test_lcore_var);
415