Commit 45608a43 by Alan Modra Committed by Alan Modra

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
parent b1c83c23
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
......
...@@ -109,7 +109,7 @@ gomp_init_thread_affinity (pthread_attr_t *attr) ...@@ -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);
......
...@@ -101,9 +101,3 @@ cpu_relax (void) ...@@ -101,9 +101,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__asm volatile ("wmb" : : : "memory");
}
...@@ -67,9 +67,3 @@ cpu_relax (void) ...@@ -67,9 +67,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}
...@@ -86,9 +86,3 @@ cpu_relax (void) ...@@ -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 ();
}
/* 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) ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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;
......
...@@ -64,9 +64,3 @@ cpu_relax (void) ...@@ -64,9 +64,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}
...@@ -84,9 +84,3 @@ cpu_relax (void) ...@@ -84,9 +84,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__asm volatile ("eieio" : : : "memory");
}
/* 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 * ...@@ -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) ...@@ -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))
......
/* 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 @@ ...@@ -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) ...@@ -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)
......
...@@ -76,9 +76,3 @@ cpu_relax (void) ...@@ -76,9 +76,3 @@ cpu_relax (void)
{ {
__asm volatile ("" : : : "memory"); __asm volatile ("" : : : "memory");
} }
static inline void
atomic_write_barrier (void)
{
__sync_synchronize ();
}
...@@ -96,13 +96,3 @@ cpu_relax (void) ...@@ -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
}
...@@ -145,9 +145,3 @@ cpu_relax (void) ...@@ -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 ();
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment