tinycc-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Tinycc-devel] [PATCH] stdatomic: simple counter test


From: Dmitry Selyutin
Subject: [Tinycc-devel] [PATCH] stdatomic: simple counter test
Date: Mon, 5 Apr 2021 20:57:58 +0300

Hello,
the patch below adds a simple test for atomics, which simply forks
several threads and increments a counter inside each thread in a loop.
There are in fact two tests: the first one increments the counter via
atomic_fetch_add, the second one makes use of atomic_compare_echange
in another loop. Both tests use relaxed semantics (we won't be able to
see the difference, though,  Please, let me know your thoughts on
these tests and other ways to check the functionality.

---
 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 0000000..a817fc2
--- /dev/null
+++ b/tests/tests2/124_atomic_counter.c
@@ -0,0 +1,75 @@
+#include <stddef.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <pthread.h>
+#include <stdatomic.h>
+
+#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 0000000..1db2652
--- /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 1eaaa75..f21b976 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'

--
2.30.1



reply via email to

[Prev in Thread] Current Thread [Next in Thread]