17660614cSJoyce Kong /* SPDX-License-Identifier: BSD-3-Clause 27660614cSJoyce Kong * Copyright(c) 2019 Arm Limited 3471de107SMattias Rönnblom * Copyright(c) 2024 Ericsson AB 47660614cSJoyce Kong */ 57660614cSJoyce Kong 635326b61SMattias Rönnblom #include <inttypes.h> 7471de107SMattias Rönnblom #include <stdbool.h> 8471de107SMattias Rönnblom 97660614cSJoyce Kong #include <rte_bitops.h> 1035326b61SMattias Rönnblom #include <rte_cycles.h> 1135326b61SMattias Rönnblom #include <rte_launch.h> 1235326b61SMattias Rönnblom #include <rte_lcore.h> 13471de107SMattias Rönnblom #include <rte_random.h> 147660614cSJoyce Kong #include "test.h" 157660614cSJoyce Kong 16*46ce151cSDavid Marchand static unsigned int 17*46ce151cSDavid Marchand get_worker_lcore(void) 18*46ce151cSDavid Marchand { 19*46ce151cSDavid Marchand unsigned int lcore_id = rte_get_next_lcore(-1, 1, 0); 20*46ce151cSDavid Marchand 21*46ce151cSDavid Marchand /* avoid checkers (like Coverity) false positives */ 22*46ce151cSDavid Marchand RTE_VERIFY(lcore_id < RTE_MAX_LCORE); 23*46ce151cSDavid Marchand 24*46ce151cSDavid Marchand return lcore_id; 25*46ce151cSDavid Marchand } 26*46ce151cSDavid Marchand 270883d736SMattias Rönnblom #define GEN_TEST_BIT_ACCESS(test_name, set_fun, clear_fun, assign_fun, flip_fun, test_fun, size, \ 280883d736SMattias Rönnblom mod) \ 29471de107SMattias Rönnblom static int \ 30471de107SMattias Rönnblom test_name(void) \ 31471de107SMattias Rönnblom { \ 32471de107SMattias Rönnblom uint ## size ## _t reference = (uint ## size ## _t)rte_rand(); \ 33471de107SMattias Rönnblom unsigned int bit_nr; \ 340883d736SMattias Rönnblom mod uint ## size ## _t word = (uint ## size ## _t)rte_rand(); \ 35471de107SMattias Rönnblom for (bit_nr = 0; bit_nr < size; bit_nr++) { \ 36471de107SMattias Rönnblom bool reference_bit = (reference >> bit_nr) & 1; \ 37471de107SMattias Rönnblom bool assign = rte_rand() & 1; \ 38471de107SMattias Rönnblom if (assign) { \ 39471de107SMattias Rönnblom assign_fun(&word, bit_nr, reference_bit); \ 40471de107SMattias Rönnblom } else { \ 41471de107SMattias Rönnblom if (reference_bit) \ 42471de107SMattias Rönnblom set_fun(&word, bit_nr); \ 43471de107SMattias Rönnblom else \ 44471de107SMattias Rönnblom clear_fun(&word, bit_nr); \ 45471de107SMattias Rönnblom } \ 46471de107SMattias Rönnblom TEST_ASSERT(test_fun(&word, bit_nr) == reference_bit, \ 47471de107SMattias Rönnblom "Bit %d had unexpected value", bit_nr); \ 48471de107SMattias Rönnblom flip_fun(&word, bit_nr); \ 49471de107SMattias Rönnblom TEST_ASSERT(test_fun(&word, bit_nr) != reference_bit, \ 50471de107SMattias Rönnblom "Bit %d had unflipped value", bit_nr); \ 51471de107SMattias Rönnblom flip_fun(&word, bit_nr); \ 520883d736SMattias Rönnblom const mod uint ## size ## _t *const_ptr = &word; \ 53471de107SMattias Rönnblom TEST_ASSERT(test_fun(const_ptr, bit_nr) == reference_bit, \ 54471de107SMattias Rönnblom "Bit %d had unexpected value", bit_nr); \ 55471de107SMattias Rönnblom } \ 56471de107SMattias Rönnblom for (bit_nr = 0; bit_nr < size; bit_nr++) { \ 57471de107SMattias Rönnblom bool reference_bit = (reference >> bit_nr) & 1; \ 58471de107SMattias Rönnblom TEST_ASSERT(test_fun(&word, bit_nr) == reference_bit, \ 59471de107SMattias Rönnblom "Bit %d had unexpected value", bit_nr); \ 60471de107SMattias Rönnblom } \ 61471de107SMattias Rönnblom TEST_ASSERT(reference == word, "Word had unexpected value"); \ 62471de107SMattias Rönnblom return TEST_SUCCESS; \ 63471de107SMattias Rönnblom } 64471de107SMattias Rönnblom 65471de107SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_access32, rte_bit_set, rte_bit_clear, rte_bit_assign, rte_bit_flip, 660883d736SMattias Rönnblom rte_bit_test, 32,) 67471de107SMattias Rönnblom 68471de107SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_access64, rte_bit_set, rte_bit_clear, rte_bit_assign, rte_bit_flip, 690883d736SMattias Rönnblom rte_bit_test, 64,) 700883d736SMattias Rönnblom 710883d736SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_v_access32, rte_bit_set, rte_bit_clear, rte_bit_assign, rte_bit_flip, 720883d736SMattias Rönnblom rte_bit_test, 32, volatile) 730883d736SMattias Rönnblom 740883d736SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_v_access64, rte_bit_set, rte_bit_clear, rte_bit_assign, rte_bit_flip, 750883d736SMattias Rönnblom rte_bit_test, 64, volatile) 76471de107SMattias Rönnblom 7735326b61SMattias Rönnblom #define bit_atomic_set(addr, nr) \ 7835326b61SMattias Rönnblom rte_bit_atomic_set(addr, nr, rte_memory_order_relaxed) 7935326b61SMattias Rönnblom 8035326b61SMattias Rönnblom #define bit_atomic_clear(addr, nr) \ 8135326b61SMattias Rönnblom rte_bit_atomic_clear(addr, nr, rte_memory_order_relaxed) 8235326b61SMattias Rönnblom 8335326b61SMattias Rönnblom #define bit_atomic_assign(addr, nr, value) \ 8435326b61SMattias Rönnblom rte_bit_atomic_assign(addr, nr, value, rte_memory_order_relaxed) 8535326b61SMattias Rönnblom 8635326b61SMattias Rönnblom #define bit_atomic_flip(addr, nr) \ 8735326b61SMattias Rönnblom rte_bit_atomic_flip(addr, nr, rte_memory_order_relaxed) 8835326b61SMattias Rönnblom 8935326b61SMattias Rönnblom #define bit_atomic_test(addr, nr) \ 9035326b61SMattias Rönnblom rte_bit_atomic_test(addr, nr, rte_memory_order_relaxed) 9135326b61SMattias Rönnblom 9235326b61SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_atomic_access32, bit_atomic_set, bit_atomic_clear, bit_atomic_assign, 930883d736SMattias Rönnblom bit_atomic_flip, bit_atomic_test, 32,) 9435326b61SMattias Rönnblom 9535326b61SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_atomic_access64, bit_atomic_set, bit_atomic_clear, bit_atomic_assign, 960883d736SMattias Rönnblom bit_atomic_flip, bit_atomic_test, 64,) 970883d736SMattias Rönnblom 980883d736SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_atomic_v_access32, bit_atomic_set, bit_atomic_clear, bit_atomic_assign, 990883d736SMattias Rönnblom bit_atomic_flip, bit_atomic_test, 32, volatile) 1000883d736SMattias Rönnblom 1010883d736SMattias Rönnblom GEN_TEST_BIT_ACCESS(test_bit_atomic_v_access64, bit_atomic_set, bit_atomic_clear, bit_atomic_assign, 1020883d736SMattias Rönnblom bit_atomic_flip, bit_atomic_test, 64, volatile) 10335326b61SMattias Rönnblom 10435326b61SMattias Rönnblom #define PARALLEL_TEST_RUNTIME 0.25 10535326b61SMattias Rönnblom 10635326b61SMattias Rönnblom #define GEN_TEST_BIT_PARALLEL_ASSIGN(size) \ 10735326b61SMattias Rönnblom struct parallel_access_lcore ## size \ 10835326b61SMattias Rönnblom { \ 10935326b61SMattias Rönnblom unsigned int bit; \ 11035326b61SMattias Rönnblom uint ## size ##_t *word; \ 11135326b61SMattias Rönnblom bool failed; \ 11235326b61SMattias Rönnblom }; \ 11335326b61SMattias Rönnblom static int \ 11435326b61SMattias Rönnblom run_parallel_assign ## size(void *arg) \ 11535326b61SMattias Rönnblom { \ 11635326b61SMattias Rönnblom struct parallel_access_lcore ## size *lcore = arg; \ 11735326b61SMattias Rönnblom uint64_t deadline = rte_get_timer_cycles() + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ 11835326b61SMattias Rönnblom bool value = false; \ 11935326b61SMattias Rönnblom do { \ 12035326b61SMattias Rönnblom bool new_value = rte_rand() & 1; \ 12135326b61SMattias Rönnblom bool use_test_and_modify = rte_rand() & 1; \ 12235326b61SMattias Rönnblom bool use_assign = rte_rand() & 1; \ 12335326b61SMattias Rönnblom if (rte_bit_atomic_test(lcore->word, lcore->bit, \ 12435326b61SMattias Rönnblom rte_memory_order_relaxed) != value) { \ 12535326b61SMattias Rönnblom lcore->failed = true; \ 12635326b61SMattias Rönnblom break; \ 12735326b61SMattias Rönnblom } \ 12835326b61SMattias Rönnblom if (use_test_and_modify) { \ 12935326b61SMattias Rönnblom bool old_value; \ 13035326b61SMattias Rönnblom if (use_assign) { \ 13135326b61SMattias Rönnblom old_value = rte_bit_atomic_test_and_assign(lcore->word, \ 13235326b61SMattias Rönnblom lcore->bit, new_value, rte_memory_order_relaxed); \ 13335326b61SMattias Rönnblom } else { \ 13435326b61SMattias Rönnblom old_value = new_value ? \ 13535326b61SMattias Rönnblom rte_bit_atomic_test_and_set(lcore->word, lcore->bit, \ 13635326b61SMattias Rönnblom rte_memory_order_relaxed) : \ 13735326b61SMattias Rönnblom rte_bit_atomic_test_and_clear(lcore->word, lcore->bit, \ 13835326b61SMattias Rönnblom rte_memory_order_relaxed); \ 13935326b61SMattias Rönnblom } \ 14035326b61SMattias Rönnblom if (old_value != value) { \ 14135326b61SMattias Rönnblom lcore->failed = true; \ 14235326b61SMattias Rönnblom break; \ 14335326b61SMattias Rönnblom } \ 14435326b61SMattias Rönnblom } else { \ 14535326b61SMattias Rönnblom if (use_assign) { \ 14635326b61SMattias Rönnblom rte_bit_atomic_assign(lcore->word, lcore->bit, new_value, \ 14735326b61SMattias Rönnblom rte_memory_order_relaxed); \ 14835326b61SMattias Rönnblom } else { \ 14935326b61SMattias Rönnblom if (new_value) \ 15035326b61SMattias Rönnblom rte_bit_atomic_set(lcore->word, lcore->bit, \ 15135326b61SMattias Rönnblom rte_memory_order_relaxed); \ 15235326b61SMattias Rönnblom else \ 15335326b61SMattias Rönnblom rte_bit_atomic_clear(lcore->word, lcore->bit, \ 15435326b61SMattias Rönnblom rte_memory_order_relaxed); \ 15535326b61SMattias Rönnblom } \ 15635326b61SMattias Rönnblom } \ 15735326b61SMattias Rönnblom value = new_value; \ 15835326b61SMattias Rönnblom } while (rte_get_timer_cycles() < deadline); \ 15935326b61SMattias Rönnblom return 0; \ 16035326b61SMattias Rönnblom } \ 16135326b61SMattias Rönnblom static int \ 16235326b61SMattias Rönnblom test_bit_atomic_parallel_assign ## size(void) \ 16335326b61SMattias Rönnblom { \ 16435326b61SMattias Rönnblom unsigned int worker_lcore_id; \ 16535326b61SMattias Rönnblom uint ## size ## _t word = 0; \ 16635326b61SMattias Rönnblom struct parallel_access_lcore ## size lmain = { .word = &word }; \ 16735326b61SMattias Rönnblom struct parallel_access_lcore ## size lworker = { .word = &word }; \ 16835326b61SMattias Rönnblom if (rte_lcore_count() < 2) { \ 16935326b61SMattias Rönnblom printf("Need multiple cores to run parallel test.\n"); \ 17035326b61SMattias Rönnblom return TEST_SKIPPED; \ 17135326b61SMattias Rönnblom } \ 172*46ce151cSDavid Marchand worker_lcore_id = get_worker_lcore(); \ 17335326b61SMattias Rönnblom lmain.bit = rte_rand_max(size); \ 17435326b61SMattias Rönnblom do { \ 17535326b61SMattias Rönnblom lworker.bit = rte_rand_max(size); \ 17635326b61SMattias Rönnblom } while (lworker.bit == lmain.bit); \ 17735326b61SMattias Rönnblom int rc = rte_eal_remote_launch(run_parallel_assign ## size, &lworker, worker_lcore_id); \ 17835326b61SMattias Rönnblom TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ 17935326b61SMattias Rönnblom run_parallel_assign ## size(&lmain); \ 18035326b61SMattias Rönnblom rte_eal_mp_wait_lcore(); \ 18135326b61SMattias Rönnblom TEST_ASSERT(!lmain.failed, "Main lcore atomic access failed"); \ 18235326b61SMattias Rönnblom TEST_ASSERT(!lworker.failed, "Worker lcore atomic access failed"); \ 18335326b61SMattias Rönnblom return TEST_SUCCESS; \ 18435326b61SMattias Rönnblom } 18535326b61SMattias Rönnblom 18635326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_ASSIGN(32) 18735326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_ASSIGN(64) 18835326b61SMattias Rönnblom 18935326b61SMattias Rönnblom #define GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(size) \ 19035326b61SMattias Rönnblom struct parallel_test_and_set_lcore ## size \ 19135326b61SMattias Rönnblom { \ 19235326b61SMattias Rönnblom uint ## size ##_t *word; \ 19335326b61SMattias Rönnblom unsigned int bit; \ 19435326b61SMattias Rönnblom uint64_t flips; \ 19535326b61SMattias Rönnblom }; \ 19635326b61SMattias Rönnblom static int \ 19735326b61SMattias Rönnblom run_parallel_test_and_modify ## size(void *arg) \ 19835326b61SMattias Rönnblom { \ 19935326b61SMattias Rönnblom struct parallel_test_and_set_lcore ## size *lcore = arg; \ 20035326b61SMattias Rönnblom uint64_t deadline = rte_get_timer_cycles() + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ 20135326b61SMattias Rönnblom do { \ 20235326b61SMattias Rönnblom bool old_value; \ 20335326b61SMattias Rönnblom bool new_value = rte_rand() & 1; \ 20435326b61SMattias Rönnblom bool use_assign = rte_rand() & 1; \ 20535326b61SMattias Rönnblom if (use_assign) \ 20635326b61SMattias Rönnblom old_value = rte_bit_atomic_test_and_assign(lcore->word, lcore->bit, \ 20735326b61SMattias Rönnblom new_value, rte_memory_order_relaxed); \ 20835326b61SMattias Rönnblom else \ 20935326b61SMattias Rönnblom old_value = new_value ? \ 21035326b61SMattias Rönnblom rte_bit_atomic_test_and_set(lcore->word, lcore->bit, \ 21135326b61SMattias Rönnblom rte_memory_order_relaxed) : \ 21235326b61SMattias Rönnblom rte_bit_atomic_test_and_clear(lcore->word, lcore->bit, \ 21335326b61SMattias Rönnblom rte_memory_order_relaxed); \ 21435326b61SMattias Rönnblom if (old_value != new_value) \ 21535326b61SMattias Rönnblom lcore->flips++; \ 21635326b61SMattias Rönnblom } while (rte_get_timer_cycles() < deadline); \ 21735326b61SMattias Rönnblom return 0; \ 21835326b61SMattias Rönnblom } \ 21935326b61SMattias Rönnblom static int \ 22035326b61SMattias Rönnblom test_bit_atomic_parallel_test_and_modify ## size(void) \ 22135326b61SMattias Rönnblom { \ 22235326b61SMattias Rönnblom unsigned int worker_lcore_id; \ 22335326b61SMattias Rönnblom uint ## size ## _t word = 0; \ 22435326b61SMattias Rönnblom unsigned int bit = rte_rand_max(size); \ 22535326b61SMattias Rönnblom struct parallel_test_and_set_lcore ## size lmain = { .word = &word, .bit = bit }; \ 22635326b61SMattias Rönnblom struct parallel_test_and_set_lcore ## size lworker = { .word = &word, .bit = bit }; \ 22735326b61SMattias Rönnblom if (rte_lcore_count() < 2) { \ 22835326b61SMattias Rönnblom printf("Need multiple cores to run parallel test.\n"); \ 22935326b61SMattias Rönnblom return TEST_SKIPPED; \ 23035326b61SMattias Rönnblom } \ 231*46ce151cSDavid Marchand worker_lcore_id = get_worker_lcore(); \ 23235326b61SMattias Rönnblom int rc = rte_eal_remote_launch(run_parallel_test_and_modify ## size, &lworker, \ 23335326b61SMattias Rönnblom worker_lcore_id); \ 23435326b61SMattias Rönnblom TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ 23535326b61SMattias Rönnblom run_parallel_test_and_modify ## size(&lmain); \ 23635326b61SMattias Rönnblom rte_eal_mp_wait_lcore(); \ 23735326b61SMattias Rönnblom uint64_t total_flips = lmain.flips + lworker.flips; \ 23835326b61SMattias Rönnblom bool expected_value = total_flips % 2; \ 23935326b61SMattias Rönnblom TEST_ASSERT(expected_value == rte_bit_test(&word, bit), \ 24035326b61SMattias Rönnblom "After %"PRId64" flips, the bit value should be %d", total_flips, expected_value); \ 241899cffe0SMattias Rönnblom uint ## size ## _t expected_word = 0; \ 24235326b61SMattias Rönnblom rte_bit_assign(&expected_word, bit, expected_value); \ 24335326b61SMattias Rönnblom TEST_ASSERT(expected_word == word, "Untouched bits have changed value"); \ 24435326b61SMattias Rönnblom return TEST_SUCCESS; \ 24535326b61SMattias Rönnblom } 24635326b61SMattias Rönnblom 24735326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(32) 24835326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_TEST_AND_MODIFY(64) 24935326b61SMattias Rönnblom 25035326b61SMattias Rönnblom #define GEN_TEST_BIT_PARALLEL_FLIP(size) \ 25135326b61SMattias Rönnblom struct parallel_flip_lcore ## size \ 25235326b61SMattias Rönnblom { \ 25335326b61SMattias Rönnblom uint ## size ##_t *word; \ 25435326b61SMattias Rönnblom unsigned int bit; \ 25535326b61SMattias Rönnblom uint64_t flips; \ 25635326b61SMattias Rönnblom }; \ 25735326b61SMattias Rönnblom static int \ 25835326b61SMattias Rönnblom run_parallel_flip ## size(void *arg) \ 25935326b61SMattias Rönnblom { \ 26035326b61SMattias Rönnblom struct parallel_flip_lcore ## size *lcore = arg; \ 26135326b61SMattias Rönnblom uint64_t deadline = rte_get_timer_cycles() + PARALLEL_TEST_RUNTIME * rte_get_timer_hz(); \ 26235326b61SMattias Rönnblom do { \ 26335326b61SMattias Rönnblom rte_bit_atomic_flip(lcore->word, lcore->bit, rte_memory_order_relaxed); \ 26435326b61SMattias Rönnblom lcore->flips++; \ 26535326b61SMattias Rönnblom } while (rte_get_timer_cycles() < deadline); \ 26635326b61SMattias Rönnblom return 0; \ 26735326b61SMattias Rönnblom } \ 26835326b61SMattias Rönnblom static int \ 26935326b61SMattias Rönnblom test_bit_atomic_parallel_flip ## size(void) \ 27035326b61SMattias Rönnblom { \ 27135326b61SMattias Rönnblom unsigned int worker_lcore_id; \ 27235326b61SMattias Rönnblom uint ## size ## _t word = 0; \ 27335326b61SMattias Rönnblom unsigned int bit = rte_rand_max(size); \ 27435326b61SMattias Rönnblom struct parallel_flip_lcore ## size lmain = { .word = &word, .bit = bit }; \ 27535326b61SMattias Rönnblom struct parallel_flip_lcore ## size lworker = { .word = &word, .bit = bit }; \ 27635326b61SMattias Rönnblom if (rte_lcore_count() < 2) { \ 27735326b61SMattias Rönnblom printf("Need multiple cores to run parallel test.\n"); \ 27835326b61SMattias Rönnblom return TEST_SKIPPED; \ 27935326b61SMattias Rönnblom } \ 280*46ce151cSDavid Marchand worker_lcore_id = get_worker_lcore(); \ 28135326b61SMattias Rönnblom int rc = rte_eal_remote_launch(run_parallel_flip ## size, &lworker, worker_lcore_id); \ 28235326b61SMattias Rönnblom TEST_ASSERT(rc == 0, "Worker thread launch failed"); \ 28335326b61SMattias Rönnblom run_parallel_flip ## size(&lmain); \ 28435326b61SMattias Rönnblom rte_eal_mp_wait_lcore(); \ 28535326b61SMattias Rönnblom uint64_t total_flips = lmain.flips + lworker.flips; \ 28635326b61SMattias Rönnblom bool expected_value = total_flips % 2; \ 28735326b61SMattias Rönnblom TEST_ASSERT(expected_value == rte_bit_test(&word, bit), \ 28835326b61SMattias Rönnblom "After %"PRId64" flips, the bit value should be %d", total_flips, expected_value); \ 289899cffe0SMattias Rönnblom uint ## size ## _t expected_word = 0; \ 29035326b61SMattias Rönnblom rte_bit_assign(&expected_word, bit, expected_value); \ 29135326b61SMattias Rönnblom TEST_ASSERT(expected_word == word, "Untouched bits have changed value"); \ 29235326b61SMattias Rönnblom return TEST_SUCCESS; \ 29335326b61SMattias Rönnblom } 29435326b61SMattias Rönnblom 29535326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_FLIP(32) 29635326b61SMattias Rönnblom GEN_TEST_BIT_PARALLEL_FLIP(64) 29735326b61SMattias Rönnblom 298471de107SMattias Rönnblom static uint32_t val32; 299471de107SMattias Rönnblom static uint64_t val64; 3007660614cSJoyce Kong 3017660614cSJoyce Kong #define MAX_BITS_32 32 3027660614cSJoyce Kong #define MAX_BITS_64 64 3037660614cSJoyce Kong 3047660614cSJoyce Kong /* 3057660614cSJoyce Kong * Bitops functions 3067660614cSJoyce Kong * ================ 3077660614cSJoyce Kong * 3087660614cSJoyce Kong * - The main test function performs several subtests. 3097660614cSJoyce Kong * - Check bit operations on one core. 3107660614cSJoyce Kong * - Initialize valXX to specified values, then set each bit of valXX 3117660614cSJoyce Kong * to 1 one by one in "test_bit_relaxed_set". 3127660614cSJoyce Kong * 3137660614cSJoyce Kong * - Clear each bit of valXX to 0 one by one in "test_bit_relaxed_clear". 3147660614cSJoyce Kong * 3157660614cSJoyce Kong * - Function "test_bit_relaxed_test_set_clear" checks whether each bit 3167660614cSJoyce Kong * of valXX can do "test and set" and "test and clear" correctly. 3177660614cSJoyce Kong */ 3187660614cSJoyce Kong 3197660614cSJoyce Kong static int 3207660614cSJoyce Kong test_bit_relaxed_set(void) 3217660614cSJoyce Kong { 3227660614cSJoyce Kong unsigned int i; 3237660614cSJoyce Kong 3247660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3257660614cSJoyce Kong rte_bit_relaxed_set32(i, &val32); 3267660614cSJoyce Kong 3277660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3287660614cSJoyce Kong if (!rte_bit_relaxed_get32(i, &val32)) { 3297660614cSJoyce Kong printf("Failed to set bit in relaxed version.\n"); 3307660614cSJoyce Kong return TEST_FAILED; 3317660614cSJoyce Kong } 3327660614cSJoyce Kong 3337660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3347660614cSJoyce Kong rte_bit_relaxed_set64(i, &val64); 3357660614cSJoyce Kong 3367660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3377660614cSJoyce Kong if (!rte_bit_relaxed_get64(i, &val64)) { 3387660614cSJoyce Kong printf("Failed to set bit in relaxed version.\n"); 3397660614cSJoyce Kong return TEST_FAILED; 3407660614cSJoyce Kong } 3417660614cSJoyce Kong 3427660614cSJoyce Kong return TEST_SUCCESS; 3437660614cSJoyce Kong } 3447660614cSJoyce Kong 3457660614cSJoyce Kong static int 3467660614cSJoyce Kong test_bit_relaxed_clear(void) 3477660614cSJoyce Kong { 3487660614cSJoyce Kong unsigned int i; 3497660614cSJoyce Kong 3507660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3517660614cSJoyce Kong rte_bit_relaxed_clear32(i, &val32); 3527660614cSJoyce Kong 3537660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3547660614cSJoyce Kong if (rte_bit_relaxed_get32(i, &val32)) { 3557660614cSJoyce Kong printf("Failed to clear bit in relaxed version.\n"); 3567660614cSJoyce Kong return TEST_FAILED; 3577660614cSJoyce Kong } 3587660614cSJoyce Kong 3597660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3607660614cSJoyce Kong rte_bit_relaxed_clear64(i, &val64); 3617660614cSJoyce Kong 3627660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3637660614cSJoyce Kong if (rte_bit_relaxed_get64(i, &val64)) { 3647660614cSJoyce Kong printf("Failed to clear bit in relaxed version.\n"); 3657660614cSJoyce Kong return TEST_FAILED; 3667660614cSJoyce Kong } 3677660614cSJoyce Kong 3687660614cSJoyce Kong return TEST_SUCCESS; 3697660614cSJoyce Kong } 3707660614cSJoyce Kong 3717660614cSJoyce Kong static int 3727660614cSJoyce Kong test_bit_relaxed_test_set_clear(void) 3737660614cSJoyce Kong { 3747660614cSJoyce Kong unsigned int i; 3757660614cSJoyce Kong 3767660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3777660614cSJoyce Kong rte_bit_relaxed_test_and_set32(i, &val32); 3787660614cSJoyce Kong 3797660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3807660614cSJoyce Kong if (!rte_bit_relaxed_test_and_clear32(i, &val32)) { 3817660614cSJoyce Kong printf("Failed to set and test bit in relaxed version.\n"); 3827660614cSJoyce Kong return TEST_FAILED; 3837660614cSJoyce Kong } 3847660614cSJoyce Kong 3857660614cSJoyce Kong for (i = 0; i < MAX_BITS_32; i++) 3867660614cSJoyce Kong if (rte_bit_relaxed_get32(i, &val32)) { 3877660614cSJoyce Kong printf("Failed to test and clear bit in relaxed version.\n"); 3887660614cSJoyce Kong return TEST_FAILED; 3897660614cSJoyce Kong } 3907660614cSJoyce Kong 3917660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3927660614cSJoyce Kong rte_bit_relaxed_test_and_set64(i, &val64); 3937660614cSJoyce Kong 3947660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 3957660614cSJoyce Kong if (!rte_bit_relaxed_test_and_clear64(i, &val64)) { 3967660614cSJoyce Kong printf("Failed to set and test bit in relaxed version.\n"); 3977660614cSJoyce Kong return TEST_FAILED; 3987660614cSJoyce Kong } 3997660614cSJoyce Kong 4007660614cSJoyce Kong for (i = 0; i < MAX_BITS_64; i++) 4017660614cSJoyce Kong if (rte_bit_relaxed_get64(i, &val64)) { 4027660614cSJoyce Kong printf("Failed to test and clear bit in relaxed version.\n"); 4037660614cSJoyce Kong return TEST_FAILED; 4047660614cSJoyce Kong } 4057660614cSJoyce Kong 4067660614cSJoyce Kong return TEST_SUCCESS; 4077660614cSJoyce Kong } 4087660614cSJoyce Kong 409471de107SMattias Rönnblom static struct unit_test_suite test_suite = { 410471de107SMattias Rönnblom .suite_name = "Bitops test suite", 411471de107SMattias Rönnblom .unit_test_cases = { 412471de107SMattias Rönnblom TEST_CASE(test_bit_access32), 413471de107SMattias Rönnblom TEST_CASE(test_bit_access64), 41435326b61SMattias Rönnblom TEST_CASE(test_bit_access32), 41535326b61SMattias Rönnblom TEST_CASE(test_bit_access64), 4160883d736SMattias Rönnblom TEST_CASE(test_bit_v_access32), 4170883d736SMattias Rönnblom TEST_CASE(test_bit_v_access64), 41835326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_access32), 41935326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_access64), 4200883d736SMattias Rönnblom TEST_CASE(test_bit_atomic_v_access32), 4210883d736SMattias Rönnblom TEST_CASE(test_bit_atomic_v_access64), 42235326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_assign32), 42335326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_assign64), 42435326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_test_and_modify32), 42535326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_test_and_modify64), 42635326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_flip32), 42735326b61SMattias Rönnblom TEST_CASE(test_bit_atomic_parallel_flip64), 428471de107SMattias Rönnblom TEST_CASE(test_bit_relaxed_set), 429471de107SMattias Rönnblom TEST_CASE(test_bit_relaxed_clear), 430471de107SMattias Rönnblom TEST_CASE(test_bit_relaxed_test_set_clear), 431471de107SMattias Rönnblom TEST_CASES_END() 432471de107SMattias Rönnblom } 433471de107SMattias Rönnblom }; 434471de107SMattias Rönnblom 4357660614cSJoyce Kong static int 4367660614cSJoyce Kong test_bitops(void) 4377660614cSJoyce Kong { 438471de107SMattias Rönnblom return unit_test_suite_runner(&test_suite); 4397660614cSJoyce Kong } 4407660614cSJoyce Kong 441e0a8442cSBruce Richardson REGISTER_FAST_TEST(bitops_autotest, true, true, test_bitops); 442