affinity.c: Use atomic rather than sync builtin.

* config/linux/affinity.c: Use atomic rather than sync builtin.
	* config/linux/lock.c: Likewise.
	* config/linux/ptrlock.h: Likewise.
	* config/linux/ptrlock.c: Likewise.
	* config/linux/ptrlock.h (gomp_ptrlock_set): Always write here..
	* config/linux/ptrlock.c (gomp_ptrlock_set_slow): ..not here.
	* config/linux/futex.h (atomic_write_barrier): Delete unused function.
	* config/linux/alpha/futex.h (atomic_write_barrier): Likewise.
	* config/linux/ia64/futex.h (atomic_write_barrier): Likewise.
	* config/linux/mips/futex.h (atomic_write_barrier): Likewise.
	* config/linux/powerpc/futex.h (atomic_write_barrier): Likewise.
	* config/linux/s390/futex.h (atomic_write_barrier): Likewise.
	* config/linux/sparc/futex.h (atomic_write_barrier): Likewise.
	* config/linux/x86/futex.h (atomic_write_barrier): Likewise.

From-SVN: r181906
This commit is contained in:
Alan Modra 2011-12-02 21:24:02 +10:30 committed by Alan Modra
parent b1c83c2380
commit 45608a43c4
13 changed files with 58 additions and 71 deletions

View File

@ -1,3 +1,20 @@
2011-12-02 Alan Modra <amodra@gmail.com>
* config/linux/affinity.c: Use atomic rather than sync builtin.
* config/linux/lock.c: Likewise.
* config/linux/ptrlock.h: Likewise.
* config/linux/ptrlock.c: Likewise.
* config/linux/ptrlock.h (gomp_ptrlock_set): Always write here..
* config/linux/ptrlock.c (gomp_ptrlock_set_slow): ..not here.
* config/linux/futex.h (atomic_write_barrier): Delete unused function.
* config/linux/alpha/futex.h (atomic_write_barrier): Likewise.
* config/linux/ia64/futex.h (atomic_write_barrier): Likewise.
* config/linux/mips/futex.h (atomic_write_barrier): Likewise.
* config/linux/powerpc/futex.h (atomic_write_barrier): Likewise.
* config/linux/s390/futex.h (atomic_write_barrier): Likewise.
* config/linux/sparc/futex.h (atomic_write_barrier): Likewise.
* config/linux/x86/futex.h (atomic_write_barrier): Likewise.
2011-11-30 Alan Modra <amodra@gmail.com> 2011-11-30 Alan Modra <amodra@gmail.com>
PR libgomp/51298 PR libgomp/51298

View File

@ -109,7 +109,7 @@ gomp_init_thread_affinity (pthread_attr_t *attr)
unsigned int cpu; unsigned int cpu;
cpu_set_t cpuset; cpu_set_t cpuset;
cpu = __sync_fetch_and_add (&affinity_counter, 1); cpu = __atomic_fetch_add (&affinity_counter, 1, MEMMODEL_RELAXED);
cpu %= gomp_cpu_affinity_len; cpu %= gomp_cpu_affinity_len;
CPU_ZERO (&cpuset); CPU_ZERO (&cpuset);
CPU_SET (gomp_cpu_affinity[cpu], &cpuset); CPU_SET (gomp_cpu_affinity[cpu], &cpuset);

View File

@ -101,9 +101,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__asm volatile ("wmb" : : : "memory");
}

View File

@ -67,9 +67,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}

View File

@ -86,9 +86,3 @@ cpu_relax (void)
{ {
__asm volatile ("hint @pause" : : : "memory"); __asm volatile ("hint @pause" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2005, 2008, 2009 Free Software Foundation, Inc. /* Copyright (C) 2005, 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@redhat.com>. Contributed by Richard Henderson <rth@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp). This file is part of the GNU OpenMP Library (libgomp).
@ -62,7 +62,10 @@ gomp_unset_lock_30 (omp_lock_t *lock)
int int
gomp_test_lock_30 (omp_lock_t *lock) gomp_test_lock_30 (omp_lock_t *lock)
{ {
return __sync_bool_compare_and_swap (lock, 0, 1); int oldval = 0;
return __atomic_compare_exchange_n (lock, &oldval, 1, false,
MEMMODEL_ACQUIRE, MEMMODEL_RELAXED);
} }
void void
@ -104,11 +107,14 @@ int
gomp_test_nest_lock_30 (omp_nest_lock_t *lock) gomp_test_nest_lock_30 (omp_nest_lock_t *lock)
{ {
void *me = gomp_icv (true); void *me = gomp_icv (true);
int oldval;
if (lock->owner == me) if (lock->owner == me)
return ++lock->count; return ++lock->count;
if (__sync_bool_compare_and_swap (&lock->lock, 0, 1)) oldval = 0;
if (__atomic_compare_exchange_n (&lock->lock, &oldval, 1, false,
MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{ {
lock->owner = me; lock->owner = me;
lock->count = 1; lock->count = 1;
@ -184,8 +190,9 @@ gomp_set_nest_lock_25 (omp_nest_lock_25_t *lock)
while (1) while (1)
{ {
otid = __sync_val_compare_and_swap (&lock->owner, 0, tid); otid = 0;
if (otid == 0) if (__atomic_compare_exchange_n (&lock->owner, &otid, tid, false,
MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{ {
lock->count = 1; lock->count = 1;
return; return;
@ -207,7 +214,7 @@ gomp_unset_nest_lock_25 (omp_nest_lock_25_t *lock)
if (--lock->count == 0) if (--lock->count == 0)
{ {
__sync_lock_release (&lock->owner); __atomic_store_n (&lock->owner, 0, MEMMODEL_RELEASE);
futex_wake (&lock->owner, 1); futex_wake (&lock->owner, 1);
} }
} }
@ -217,8 +224,9 @@ gomp_test_nest_lock_25 (omp_nest_lock_25_t *lock)
{ {
int otid, tid = gomp_tid (); int otid, tid = gomp_tid ();
otid = __sync_val_compare_and_swap (&lock->owner, 0, tid); otid = 0;
if (otid == 0) if (__atomic_compare_exchange_n (&lock->owner, &otid, tid, false,
MEMMODEL_ACQUIRE, MEMMODEL_RELAXED))
{ {
lock->count = 1; lock->count = 1;
return 1; return 1;

View File

@ -64,9 +64,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}

View File

@ -84,9 +84,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__asm volatile ("eieio" : : : "memory");
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. /* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>. Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp). This file is part of the GNU OpenMP Library (libgomp).
@ -34,7 +34,10 @@ void *
gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock) gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock)
{ {
int *intptr; int *intptr;
__sync_bool_compare_and_swap (ptrlock, 1, 2); uintptr_t oldval = 1;
__atomic_compare_exchange_n (ptrlock, &oldval, 2, false,
MEMMODEL_RELAXED, MEMMODEL_RELAXED);
/* futex works on ints, not pointers. /* futex works on ints, not pointers.
But a valid work share pointer will be at least But a valid work share pointer will be at least
@ -53,11 +56,10 @@ gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock)
} }
void void
gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr) gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock)
{ {
int *intptr; int *intptr;
*ptrlock = ptr;
__asm volatile ("" : "=r" (intptr) : "0" (ptrlock)); __asm volatile ("" : "=r" (intptr) : "0" (ptrlock));
#if __BYTE_ORDER == __BIG_ENDIAN #if __BYTE_ORDER == __BIG_ENDIAN
if (sizeof (*ptrlock) > sizeof (int)) if (sizeof (*ptrlock) > sizeof (int))

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2008, 2009 Free Software Foundation, Inc. /* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
Contributed by Jakub Jelinek <jakub@redhat.com>. Contributed by Jakub Jelinek <jakub@redhat.com>.
This file is part of the GNU OpenMP Library (libgomp). This file is part of the GNU OpenMP Library (libgomp).
@ -24,7 +24,14 @@
/* This is a Linux specific implementation of a mutex synchronization /* This is a Linux specific implementation of a mutex synchronization
mechanism for libgomp. This type is private to the library. This mechanism for libgomp. This type is private to the library. This
implementation uses atomic instructions and the futex syscall. */ implementation uses atomic instructions and the futex syscall.
A ptrlock has four states:
0/NULL Initial
1 Owned by me, I get to write a pointer to ptrlock.
2 Some thread is waiting on the ptrlock.
>2 Ptrlock contains a valid pointer.
It is not valid to gain the ptrlock and then write a NULL to it. */
#ifndef GOMP_PTRLOCK_H #ifndef GOMP_PTRLOCK_H
#define GOMP_PTRLOCK_H 1 #define GOMP_PTRLOCK_H 1
@ -39,20 +46,25 @@ static inline void gomp_ptrlock_init (gomp_ptrlock_t *ptrlock, void *ptr)
extern void *gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock); extern void *gomp_ptrlock_get_slow (gomp_ptrlock_t *ptrlock);
static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock) static inline void *gomp_ptrlock_get (gomp_ptrlock_t *ptrlock)
{ {
uintptr_t oldval;
if ((uintptr_t) *ptrlock > 2) if ((uintptr_t) *ptrlock > 2)
return *ptrlock; return *ptrlock;
if (__sync_bool_compare_and_swap (ptrlock, NULL, (uintptr_t) 1)) oldval = 0;
if (__atomic_compare_exchange_n (ptrlock, &oldval, 1, false,
MEMMODEL_ACQUIRE, MEMMODEL_ACQUIRE))
return NULL; return NULL;
return gomp_ptrlock_get_slow (ptrlock); return gomp_ptrlock_get_slow (ptrlock);
} }
extern void gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock, void *ptr); extern void gomp_ptrlock_set_slow (gomp_ptrlock_t *ptrlock);
static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr) static inline void gomp_ptrlock_set (gomp_ptrlock_t *ptrlock, void *ptr)
{ {
if (!__sync_bool_compare_and_swap (ptrlock, (uintptr_t) 1, ptr)) void *wait = __atomic_exchange_n (ptrlock, ptr, MEMMODEL_RELEASE);
gomp_ptrlock_set_slow (ptrlock, ptr); if ((uintptr_t) wait != 1)
gomp_ptrlock_set_slow (ptrlock);
} }
static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock) static inline void gomp_ptrlock_destroy (gomp_ptrlock_t *ptrlock)

View File

@ -76,9 +76,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}

View File

@ -96,13 +96,3 @@ cpu_relax (void)
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
#endif #endif
} }
static inline void
atomic_write_barrier (void)
{
#if defined __arch64__ || defined __sparc_v9__
__asm volatile ("membar #StoreStore" : : : "memory");
#else
__sync_synchronize ();
#endif
}

View File

@ -145,9 +145,3 @@ cpu_relax (void)
{ {
__asm volatile ("rep; nop" : : : "memory"); __asm volatile ("rep; nop" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}