From 4bb3b3cec7041c0285ea82b668e8ec223d7bccf5 Mon Sep 17 00:00:00 2001 From: Dmitry Selyutin Date: Mon, 5 Apr 2021 20:48:50 +0300 Subject: [PATCH] stdatomic: simple counter test --- tests/tests2/124_atomic_counter.c | 75 ++++++++++++++++++++++++++ tests/tests2/124_atomic_counter.expect | 2 + tests/tests2/Makefile | 6 +++ 3 files changed, 83 insertions(+) create mode 100644 tests/tests2/124_atomic_counter.c create mode 100644 tests/tests2/124_atomic_counter.expect diff --git a/tests/tests2/124_atomic_counter.c b/tests/tests2/124_atomic_counter.c new file mode 100644 index 00000000..a817fc26 --- /dev/null +++ b/tests/tests2/124_atomic_counter.c @@ -0,0 +1,75 @@ +#include +#include +#include +#include +#include +#include + +#define NR_THREADS 16 +#define NR_STEPS ((uint32_t)UINT16_MAX * 4) + +#define BUG_ON(COND) \ + do { \ + if (!!(COND)) \ + abort(); \ + } while (0) + +static +void *adder_simple(void *arg) +{ + size_t step; + atomic_size_t *counter = arg; + + for (step = 0; step < NR_STEPS; ++step) + atomic_fetch_add_explicit(counter, 1, memory_order_relaxed); + + return NULL; +} + +static +void *adder_cmpxchg(void *arg) +{ + size_t step; + atomic_size_t *counter = arg; + + for (step = 0; step < NR_STEPS; ++step) { + size_t xchg; + size_t cmp = atomic_load_explicit(counter, memory_order_relaxed); + + do { + xchg = (cmp + 1); + } while (!atomic_compare_exchange_strong_explicit(counter, + &cmp, xchg, memory_order_relaxed, memory_order_relaxed)); + } + + return NULL; +} + +static +void atomic_counter_test(void *(*adder)(void *arg)) +{ + size_t index; + atomic_size_t counter; + pthread_t thread[NR_THREADS]; + + atomic_init(&counter, 0); + + for (index = 0; index < NR_THREADS; ++index) + BUG_ON(pthread_create(&thread[index], NULL, adder, (void *)&counter)); + + for (index = 0; index < NR_THREADS; ++index) + BUG_ON(pthread_join(thread[index], NULL)); + + if (atomic_load(&counter) == (NR_THREADS * NR_STEPS)) + printf("SUCCESS\n"); + else + printf("FAILURE\n"); +} + +int main(void) +{ + atomic_counter_test(adder_simple); + atomic_counter_test(adder_cmpxchg); + + return 0; +} diff --git a/tests/tests2/124_atomic_counter.expect b/tests/tests2/124_atomic_counter.expect new file mode 100644 index 00000000..1db2652c --- /dev/null +++ b/tests/tests2/124_atomic_counter.expect @@ -0,0 +1,2 @@ +SUCCESS +SUCCESS diff --git a/tests/tests2/Makefile b/tests/tests2/Makefile index 1eaaa756..f21b9762 100644 --- a/tests/tests2/Makefile +++ b/tests/tests2/Makefile @@ -116,6 +116,12 @@ ifneq ($(CONFIG_bcheck),no) 122_vla_reuse.test: FLAGS += -b endif +# this test needs pthread and is currently supported on x86 platforms +ifneq (,$(filter i386 x86_64,$(ARCH))) + SKIP += 124_atomic_counter.test +endif +124_atomic_counter.test: FLAGS += -pthread + # Filter source directory in warnings/errors (out-of-tree builds) FILTER = 2>&1 | sed -e 's,$(SRC)/,,g'