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