mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-27 11:43:34 +08:00
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>
This commit is contained in:
parent
d1babeb32d
commit
4a07fbb689
@ -33,7 +33,7 @@ extern pthread_mutex_t __pthread_free_threads_lock;
|
|||||||
void
|
void
|
||||||
__pthread_dealloc (struct __pthread *pthread)
|
__pthread_dealloc (struct __pthread *pthread)
|
||||||
{
|
{
|
||||||
if (!atomic_decrement_and_test (&pthread->nr_refs))
|
if (atomic_fetch_add_relaxed (&pthread->nr_refs, -1) != 1)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* Withdraw this thread from the thread ID lookup table. */
|
/* Withdraw this thread from the thread ID lookup table. */
|
||||||
|
@ -50,7 +50,7 @@ __pthread_exit (void *status)
|
|||||||
|
|
||||||
/* Decrease the number of threads. We use an atomic operation to
|
/* Decrease the number of threads. We use an atomic operation to
|
||||||
make sure that only the last thread calls `exit'. */
|
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. */
|
/* We are the last thread. */
|
||||||
exit (0);
|
exit (0);
|
||||||
|
|
||||||
|
@ -2614,7 +2614,7 @@ aiocb64}, since the LFS transparently replaces the old interface.
|
|||||||
@c free @ascuheap @acsmem
|
@c free @ascuheap @acsmem
|
||||||
@c libc_thread_freeres
|
@c libc_thread_freeres
|
||||||
@c libc_thread_subfreeres ok
|
@c libc_thread_subfreeres ok
|
||||||
@c atomic_decrement_and_test ok
|
@c atomic_fetch_add_relaxed ok
|
||||||
@c td_eventword ok
|
@c td_eventword ok
|
||||||
@c td_eventmask ok
|
@c td_eventmask ok
|
||||||
@c atomic_compare_exchange_bool_acq ok
|
@c atomic_compare_exchange_bool_acq ok
|
||||||
|
103
nptl/cond-perf.c
103
nptl/cond-perf.c
@ -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;
|
|
||||||
}
|
|
@ -489,7 +489,7 @@ start_thread (void *arg)
|
|||||||
the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */
|
the breakpoint reports TD_THR_RUN state rather than TD_THR_ZOMBIE. */
|
||||||
atomic_fetch_or_relaxed (&pd->cancelhandling, EXITING_BITMASK);
|
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. */
|
/* This was the last thread. */
|
||||||
exit (0);
|
exit (0);
|
||||||
|
|
||||||
|
@ -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
|
/* One less thread. Decrement the counter. If it is zero we
|
||||||
terminate the entire process. */
|
terminate the entire process. */
|
||||||
result = 0;
|
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. */
|
/* Not much left to do but to exit the thread, not the process. */
|
||||||
while (1)
|
while (1)
|
||||||
INTERNAL_SYSCALL_CALL (exit, 0);
|
INTERNAL_SYSCALL_CALL (exit, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user