mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 19:00:07 +00:00
Clean up BUSY_WAIT_NOP and atomic_delay.
This patch combines BUSY_WAIT_NOP and atomic_delay into a new atomic_spin_nop function and adjusts all clients. The new function is put into atomic.h because what is best done in a spin loop is architecture-specific, and atomics must be used for spinning. The function name is meant to tell users that this has no effect on synchronization semantics but is a performance aid for spinning.
This commit is contained in:
parent
e02920bc02
commit
4eb984d3ab
23
ChangeLog
23
ChangeLog
@ -1,3 +1,26 @@
|
|||||||
|
2015-06-30 Torvald Riegel <triegel@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/unix/sysv/linux/i386/lowlevellock.h (BUSY_WAIT_NOP): Remove.
|
||||||
|
* sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (BUSY_WAIT_NOP):
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/i386/i486/bits/atomic.h (atomic_delay): Rename to
|
||||||
|
atomic_spin_nop.
|
||||||
|
* sysdeps/x86_64/bits/atomic.h: Likewise.
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/lowlevellock.h (BUSY_WAIT_NOP): Rename
|
||||||
|
to atomic_spin_nop and move ...
|
||||||
|
* sysdeps/sparc/sparc32/sparcv9/bits/atomic.h (atomic_spin_nop):
|
||||||
|
... here and ...
|
||||||
|
* sysdeps/sparc/sparc64/bits/atomic.h: ... here.
|
||||||
|
* nptl/pthread_mutex_lock.c (__pthread_mutex_lock): Use
|
||||||
|
atomic_spin_nop instead of BUSY_WAIT_NOP.
|
||||||
|
* nptl/pthread_mutex_timedlock.c (__pthread_mutex_timedlock):
|
||||||
|
Likewise.
|
||||||
|
* sysdeps/nacl/lll_timedwait_tid.c (__lll_timedwait_tid): Likewise.
|
||||||
|
* sysdeps/nacl/lowlevellock.h (BUSY_WAIT_NOP): Remove.
|
||||||
|
(lll_wait_tid): Use atomic_spin_nop instead of BUSY_WAIT_NOP.
|
||||||
|
* nscd/nscd-client.h (__nscd_acquire_maplock): Use atomic_spin_nop
|
||||||
|
instead of atomic_delay.
|
||||||
|
|
||||||
2015-06-29 Joseph Myers <joseph@codesourcery.com>
|
2015-06-29 Joseph Myers <joseph@codesourcery.com>
|
||||||
|
|
||||||
[BZ #18613]
|
[BZ #18613]
|
||||||
|
@ -754,9 +754,10 @@ void __atomic_link_error (void);
|
|||||||
|
|
||||||
#endif /* !USE_ATOMIC_COMPILER_BUILTINS */
|
#endif /* !USE_ATOMIC_COMPILER_BUILTINS */
|
||||||
|
|
||||||
|
/* This operation does not affect synchronization semantics but can be used
|
||||||
#ifndef atomic_delay
|
in the body of a spin loop to potentially improve its efficiency. */
|
||||||
# define atomic_delay() do { /* nothing */ } while (0)
|
#ifndef atomic_spin_nop
|
||||||
|
# define atomic_spin_nop() do { /* nothing */ } while (0)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* atomic.h */
|
#endif /* atomic.h */
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <not-cancel.h>
|
#include <not-cancel.h>
|
||||||
#include "pthreadP.h"
|
#include "pthreadP.h"
|
||||||
|
#include <atomic.h>
|
||||||
#include <lowlevellock.h>
|
#include <lowlevellock.h>
|
||||||
#include <stap-probe.h>
|
#include <stap-probe.h>
|
||||||
|
|
||||||
@ -135,10 +136,7 @@ __pthread_mutex_lock (mutex)
|
|||||||
LLL_MUTEX_LOCK (mutex);
|
LLL_MUTEX_LOCK (mutex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
atomic_spin_nop ();
|
||||||
#ifdef BUSY_WAIT_NOP
|
|
||||||
BUSY_WAIT_NOP;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
while (LLL_MUTEX_TRYLOCK (mutex) != 0);
|
while (LLL_MUTEX_TRYLOCK (mutex) != 0);
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <sys/time.h>
|
#include <sys/time.h>
|
||||||
#include "pthreadP.h"
|
#include "pthreadP.h"
|
||||||
|
#include <atomic.h>
|
||||||
#include <lowlevellock.h>
|
#include <lowlevellock.h>
|
||||||
#include <not-cancel.h>
|
#include <not-cancel.h>
|
||||||
|
|
||||||
@ -125,10 +126,7 @@ pthread_mutex_timedlock (mutex, abstime)
|
|||||||
PTHREAD_MUTEX_PSHARED (mutex));
|
PTHREAD_MUTEX_PSHARED (mutex));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
atomic_spin_nop ();
|
||||||
#ifdef BUSY_WAIT_NOP
|
|
||||||
BUSY_WAIT_NOP;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
while (lll_trylock (mutex->__data.__lock) != 0);
|
while (lll_trylock (mutex->__data.__lock) != 0);
|
||||||
|
|
||||||
|
@ -378,7 +378,7 @@ __nscd_acquire_maplock (volatile struct locked_map_ptr *mapptr)
|
|||||||
if (__glibc_unlikely (++cnt > 5))
|
if (__glibc_unlikely (++cnt > 5))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
atomic_delay ();
|
atomic_spin_nop ();
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -479,7 +479,7 @@ typedef uintmax_t uatomic_max_t;
|
|||||||
__result; })
|
__result; })
|
||||||
|
|
||||||
|
|
||||||
#define atomic_delay() asm ("rep; nop")
|
#define atomic_spin_nop() asm ("rep; nop")
|
||||||
|
|
||||||
|
|
||||||
#define __arch_and_body(lock, mem, mask) \
|
#define __arch_and_body(lock, mem, mask) \
|
||||||
|
@ -40,7 +40,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
|
|||||||
finish quick enough that the timeout doesn't matter. If any
|
finish quick enough that the timeout doesn't matter. If any
|
||||||
thread ever stays in this state for long, there is something
|
thread ever stays in this state for long, there is something
|
||||||
catastrophically wrong. */
|
catastrophically wrong. */
|
||||||
BUSY_WAIT_NOP;
|
atomic_spin_nop ();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert (tid > 0);
|
assert (tid > 0);
|
||||||
|
@ -21,10 +21,6 @@
|
|||||||
/* Everything except the exit handling is the same as the generic code. */
|
/* Everything except the exit handling is the same as the generic code. */
|
||||||
# include <sysdeps/nptl/lowlevellock.h>
|
# include <sysdeps/nptl/lowlevellock.h>
|
||||||
|
|
||||||
# ifndef BUSY_WAIT_NOP
|
|
||||||
# define BUSY_WAIT_NOP __sync_synchronize ()
|
|
||||||
# endif
|
|
||||||
|
|
||||||
/* See exit-thread.h for details. */
|
/* See exit-thread.h for details. */
|
||||||
# define NACL_EXITING_TID 1
|
# define NACL_EXITING_TID 1
|
||||||
|
|
||||||
@ -36,7 +32,7 @@
|
|||||||
while ((__tid = atomic_load_relaxed (__tidp)) != 0) \
|
while ((__tid = atomic_load_relaxed (__tidp)) != 0) \
|
||||||
{ \
|
{ \
|
||||||
if (__tid == NACL_EXITING_TID) \
|
if (__tid == NACL_EXITING_TID) \
|
||||||
BUSY_WAIT_NOP; \
|
atomic_spin_nop (); \
|
||||||
else \
|
else \
|
||||||
lll_futex_wait (__tidp, __tid, LLL_PRIVATE); \
|
lll_futex_wait (__tidp, __tid, LLL_PRIVATE); \
|
||||||
} \
|
} \
|
||||||
|
@ -100,3 +100,6 @@ typedef uintmax_t uatomic_max_t;
|
|||||||
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
|
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
|
||||||
#define atomic_write_barrier() \
|
#define atomic_write_barrier() \
|
||||||
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")
|
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")
|
||||||
|
|
||||||
|
extern void __cpu_relax (void);
|
||||||
|
#define atomic_spin_nop () __cpu_relax ()
|
||||||
|
@ -121,3 +121,6 @@ typedef uintmax_t uatomic_max_t;
|
|||||||
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
|
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
|
||||||
#define atomic_write_barrier() \
|
#define atomic_write_barrier() \
|
||||||
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")
|
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")
|
||||||
|
|
||||||
|
extern void __cpu_relax (void);
|
||||||
|
#define atomic_spin_nop () __cpu_relax ()
|
||||||
|
@ -58,10 +58,6 @@
|
|||||||
#define LLL_LOCK_INITIALIZER_WAITERS (2)
|
#define LLL_LOCK_INITIALIZER_WAITERS (2)
|
||||||
|
|
||||||
|
|
||||||
/* Delay in spinlock loop. */
|
|
||||||
#define BUSY_WAIT_NOP asm ("rep; nop")
|
|
||||||
|
|
||||||
|
|
||||||
/* NB: in the lll_trylock macro we simply return the value in %eax
|
/* NB: in the lll_trylock macro we simply return the value in %eax
|
||||||
after the cmpxchg instruction. In case the operation succeded this
|
after the cmpxchg instruction. In case the operation succeded this
|
||||||
value is zero. In case the operation failed, the cmpxchg instruction
|
value is zero. In case the operation failed, the cmpxchg instruction
|
||||||
|
@ -25,12 +25,6 @@
|
|||||||
#include <atomic.h>
|
#include <atomic.h>
|
||||||
#include <kernel-features.h>
|
#include <kernel-features.h>
|
||||||
|
|
||||||
#ifndef __sparc32_atomic_do_lock
|
|
||||||
/* Delay in spinlock loop. */
|
|
||||||
extern void __cpu_relax (void);
|
|
||||||
#define BUSY_WAIT_NOP __cpu_relax ()
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <lowlevellock-futex.h>
|
#include <lowlevellock-futex.h>
|
||||||
|
|
||||||
static inline int
|
static inline int
|
||||||
|
@ -57,9 +57,6 @@
|
|||||||
#define LLL_LOCK_INITIALIZER_LOCKED (1)
|
#define LLL_LOCK_INITIALIZER_LOCKED (1)
|
||||||
#define LLL_LOCK_INITIALIZER_WAITERS (2)
|
#define LLL_LOCK_INITIALIZER_WAITERS (2)
|
||||||
|
|
||||||
/* Delay in spinlock loop. */
|
|
||||||
#define BUSY_WAIT_NOP asm ("rep; nop")
|
|
||||||
|
|
||||||
|
|
||||||
/* NB: in the lll_trylock macro we simply return the value in %eax
|
/* NB: in the lll_trylock macro we simply return the value in %eax
|
||||||
after the cmpxchg instruction. In case the operation succeded this
|
after the cmpxchg instruction. In case the operation succeded this
|
||||||
|
@ -410,7 +410,7 @@ typedef uintmax_t uatomic_max_t;
|
|||||||
__result; })
|
__result; })
|
||||||
|
|
||||||
|
|
||||||
#define atomic_delay() asm ("rep; nop")
|
#define atomic_spin_nop() asm ("rep; nop")
|
||||||
|
|
||||||
|
|
||||||
#define __arch_and_body(lock, mem, mask) \
|
#define __arch_and_body(lock, mem, mask) \
|
||||||
|
Loading…
Reference in New Issue
Block a user