aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWilco Dijkstra <wdijkstr@arm.com>2022-09-22 15:40:37 +0100
committerWilco Dijkstra <wdijkstr@arm.com>2022-09-23 15:59:56 +0100
commit4a07fbb689eeec30e7d71a0d144c26e0d1e424ac (patch)
tree85d53e165fb64b144ce9ac3018cd90afdd70bf4f
parentd1babeb32de5dae8893c640bd925357b218d846c (diff)
downloadglibc-4a07fbb689eeec30e7d71a0d144c26e0d1e424ac.zip
glibc-4a07fbb689eeec30e7d71a0d144c26e0d1e424ac.tar.gz
glibc-4a07fbb689eeec30e7d71a0d144c26e0d1e424ac.tar.bz2
Use C11 atomics instead of atomic_decrement_and_test
Replace atomic_decrement_and_test with atomic_fetch_add_relaxed. These are simple counters which do not protect any shared data from concurrent accesses. Also remove the unused file cond-perf.c. Passes regress on AArch64. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
-rw-r--r--htl/pt-dealloc.c2
-rw-r--r--htl/pt-exit.c2
-rw-r--r--manual/llio.texi2
-rw-r--r--nptl/cond-perf.c103
-rw-r--r--nptl/pthread_create.c2
-rw-r--r--sysdeps/nptl/libc_start_call_main.h2
6 files changed, 5 insertions, 108 deletions
diff --git a/htl/pt-dealloc.c b/htl/pt-dealloc.c
index c776e34..86bbb30 100644
--- a/htl/pt-dealloc.c
+++ b/htl/pt-dealloc.c
@@ -33,7 +33,7 @@ extern pthread_mutex_t __pthread_free_threads_lock;
void
__pthread_dealloc (struct __pthread *pthread)
{
- if (!atomic_decrement_and_test (&pthread->nr_refs))
+ if (atomic_fetch_add_relaxed (&pthread->nr_refs, -1) != 1)
return;
/* Withdraw this thread from the thread ID lookup table. */
diff --git a/htl/pt-exit.c b/htl/pt-exit.c
index f0759c8..3c0a8c5 100644
--- a/htl/pt-exit.c
+++ b/htl/pt-exit.c
@@ -50,7 +50,7 @@ __pthread_exit (void *status)
/* Decrease the number of threads. We use an atomic operation to
make sure that only the last thread calls `exit'. */
- if (atomic_decrement_and_test (&__pthread_total))
+ if (atomic_fetch_add_relaxed (&__pthread_total, -1) == 1)
/* We are the last thread. */
exit (0);
diff --git a/manual/llio.texi b/manual/llio.texi
index 79cf4c1..85201a4 100644
--- a/manual/llio.texi
+++ b/manual/llio.texi
@@ -2614,7 +2614,7 @@ aiocb64}, since the LFS transparently replaces the old interface.
@c free @ascuheap @acsmem
@c libc_thread_freeres
@c libc_thread_subfreeres ok
-@c atomic_decrement_and_test ok
+@c atomic_fetch_add_relaxed ok
@c td_eventword ok
@c td_eventmask ok
@c atomic_compare_exchange_bool_acq ok
diff --git a/nptl/cond-perf.c b/nptl/cond-perf.c
deleted file mode 100644
index 9c9488e..0000000
--- a/nptl/cond-perf.c
+++ /dev/null
@@ -1,103 +0,0 @@
-#include <pthread.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#include <atomic.h>
-
-static pthread_cond_t cond1 = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t mut1 = PTHREAD_MUTEX_INITIALIZER;
-
-static pthread_cond_t cond2 = PTHREAD_COND_INITIALIZER;
-static pthread_mutex_t mut2 = PTHREAD_MUTEX_INITIALIZER;
-
-static bool last_round;
-static int ntogo;
-static bool alldone;
-
-
-static void *
-cons (void *arg)
-{
- pthread_mutex_lock (&mut1);
-
- do
- {
- if (atomic_decrement_and_test (&ntogo))
- {
- pthread_mutex_lock (&mut2);
- alldone = true;
- pthread_cond_signal (&cond2);
- pthread_mutex_unlock (&mut2);
- }
-
- pthread_cond_wait (&cond1, &mut1);
- }
- while (! last_round);
-
- pthread_mutex_unlock (&mut1);
-
- return NULL;
-}
-
-
-int
-main (int argc, char *argv[])
-{
- int opt;
- int err;
- int nthreads = 10;
- int nrounds = 100;
- bool keeplock = false;
-
- while ((opt = getopt (argc, argv, "n:r:k")) != -1)
- switch (opt)
- {
- case 'n':
- nthreads = atol (optarg);
- break;
- case 'r':
- nrounds = atol (optarg);
- break;
- case 'k':
- keeplock = true;
- break;
- }
-
- ntogo = nthreads;
-
- pthread_t th[nthreads];
- int i;
- for (i = 0; __builtin_expect (i < nthreads, 1); ++i)
- if (__glibc_unlikely ((err = pthread_create (&th[i], NULL, cons, (void *) (long) i)) != 0))
- printf ("pthread_create: %s\n", strerror (err));
-
- for (i = 0; __builtin_expect (i < nrounds, 1); ++i)
- {
- pthread_mutex_lock (&mut2);
- while (! alldone)
- pthread_cond_wait (&cond2, &mut2);
- pthread_mutex_unlock (&mut2);
-
- pthread_mutex_lock (&mut1);
- if (! keeplock)
- pthread_mutex_unlock (&mut1);
-
- ntogo = nthreads;
- alldone = false;
- if (i + 1 >= nrounds)
- last_round = true;
-
- pthread_cond_broadcast (&cond1);
-
- if (keeplock)
- pthread_mutex_unlock (&mut1);
- }
-
- for (i = 0; i < nthreads; ++i)
- if ((err = pthread_join (th[i], NULL)) != 0)
- printf ("pthread_create: %s\n", strerror (err));
-
- return 0;
-}
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 0df6748..54afee5 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -489,7 +489,7 @@ start_thread (void *arg)
the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */
atomic_fetch_or_relaxed (&pd->cancelhandling, EXITING_BITMASK);
- if (__glibc_unlikely (atomic_decrement_and_test (&__nptl_nthreads)))
+ if (__glibc_unlikely (atomic_fetch_add_relaxed (&__nptl_nthreads, -1) == 1))
/* This was the last thread. */
exit (0);
diff --git a/sysdeps/nptl/libc_start_call_main.h b/sysdeps/nptl/libc_start_call_main.h
index a9e85f2..c10a16b 100644
--- a/sysdeps/nptl/libc_start_call_main.h
+++ b/sysdeps/nptl/libc_start_call_main.h
@@ -65,7 +65,7 @@ __libc_start_call_main (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
/* One less thread. Decrement the counter. If it is zero we
terminate the entire process. */
result = 0;
- if (! atomic_decrement_and_test (&__nptl_nthreads))
+ if (atomic_fetch_add_relaxed (&__nptl_nthreads, -1) != 1)
/* Not much left to do but to exit the thread, not the process. */
while (1)
INTERNAL_SYSCALL_CALL (exit, 0);