Skip to content

Commit

Permalink
tests: kernel: common: added test on atomic_t overflow
Browse files Browse the repository at this point in the history
Added test to verify that the value of atomic_t will be the same
in case of overflow if incremented in atomic and non-atomic manner

Signed-off-by: Alexander Razinkov <[email protected]>
  • Loading branch information
amr-sc authored and nashif committed Nov 4, 2023
1 parent 8fe8f34 commit 5725585
Showing 1 changed file with 45 additions and 0 deletions.
45 changes: 45 additions & 0 deletions tests/kernel/common/src/atomic.c
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,51 @@ ZTEST(atomic, test_threads_access_atomic)
"atomic counting failure");
}

/**
* @brief Checks that the value of atomic_t will be the same in case of overflow
* if incremented in atomic and non-atomic manner
*
* @details According to C standard the value of a signed variable
* is undefined in case of overflow. This test checks that the the value
* of atomic_t will be the same in case of overflow if incremented in atomic
* and non-atomic manner. This allows us to increment an atomic variable
* in a non-atomic manner (as long as it is logically safe)
* and expect its value to match the result of the similar atomic increment.
*
* @ingroup kernel_common_tests
*/
ZTEST(atomic, test_atomic_overflow)
{
/* Check overflow over max signed value */
uint64_t overflowed_value = (uint64_t)1 << (ATOMIC_BITS - 1);
atomic_val_t atomic_value = overflowed_value - 1;
atomic_t atomic_var = ATOMIC_INIT(atomic_value);

atomic_value++;
atomic_inc(&atomic_var);

zassert_true(atomic_value == atomic_get(&atomic_var),
"max signed overflow mismatch: %lx/%lx",
atomic_value, atomic_get(&atomic_var));
zassert_true(atomic_value == (atomic_val_t)overflowed_value,
"unexpected value after overflow: %lx, expected: %lx",
atomic_value, (atomic_val_t)overflowed_value);

/* Check overflow over max unsigned value */
atomic_value = -1;
atomic_var = ATOMIC_INIT(atomic_value);

atomic_value++;
atomic_inc(&atomic_var);

zassert_true(atomic_value == atomic_get(&atomic_var),
"max unsigned overflow mismatch: %lx/%lx",
atomic_value, atomic_get(&atomic_var));
zassert_true(atomic_value == 0,
"unexpected value after overflow: %lx, expected: 0",
atomic_value);
}

extern void *common_setup(void);
ZTEST_SUITE(atomic, NULL, common_setup, NULL, NULL, NULL);
/**
Expand Down

0 comments on commit 5725585

Please sign in to comment.