Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
Torvald Riegel committed Jun 30, 2015
1 parent e02920b commit 4eb984d
Show file tree
Hide file tree
Showing 14 changed files with 42 additions and 33 deletions.
23 changes: 23 additions & 0 deletions 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>

[BZ #18613]
Expand Down
7 changes: 4 additions & 3 deletions include/atomic.h
Expand Up @@ -754,9 +754,10 @@ void __atomic_link_error (void);

#endif /* !USE_ATOMIC_COMPILER_BUILTINS */


#ifndef atomic_delay
# define atomic_delay() do { /* nothing */ } while (0)
/* This operation does not affect synchronization semantics but can be used
in the body of a spin loop to potentially improve its efficiency. */
#ifndef atomic_spin_nop
# define atomic_spin_nop() do { /* nothing */ } while (0)
#endif

#endif /* atomic.h */
6 changes: 2 additions & 4 deletions nptl/pthread_mutex_lock.c
Expand Up @@ -23,6 +23,7 @@
#include <sys/param.h>
#include <not-cancel.h>
#include "pthreadP.h"
#include <atomic.h>
#include <lowlevellock.h>
#include <stap-probe.h>

Expand Down Expand Up @@ -135,10 +136,7 @@ __pthread_mutex_lock (mutex)
LLL_MUTEX_LOCK (mutex);
break;
}

#ifdef BUSY_WAIT_NOP
BUSY_WAIT_NOP;
#endif
atomic_spin_nop ();
}
while (LLL_MUTEX_TRYLOCK (mutex) != 0);

Expand Down
6 changes: 2 additions & 4 deletions nptl/pthread_mutex_timedlock.c
Expand Up @@ -22,6 +22,7 @@
#include <sys/param.h>
#include <sys/time.h>
#include "pthreadP.h"
#include <atomic.h>
#include <lowlevellock.h>
#include <not-cancel.h>

Expand Down Expand Up @@ -125,10 +126,7 @@ pthread_mutex_timedlock (mutex, abstime)
PTHREAD_MUTEX_PSHARED (mutex));
break;
}

#ifdef BUSY_WAIT_NOP
BUSY_WAIT_NOP;
#endif
atomic_spin_nop ();
}
while (lll_trylock (mutex->__data.__lock) != 0);

Expand Down
2 changes: 1 addition & 1 deletion nscd/nscd-client.h
Expand Up @@ -378,7 +378,7 @@ __nscd_acquire_maplock (volatile struct locked_map_ptr *mapptr)
if (__glibc_unlikely (++cnt > 5))
return false;

atomic_delay ();
atomic_spin_nop ();
}

return true;
Expand Down
2 changes: 1 addition & 1 deletion sysdeps/i386/i486/bits/atomic.h
Expand Up @@ -479,7 +479,7 @@ typedef uintmax_t uatomic_max_t;
__result; })


#define atomic_delay() asm ("rep; nop")
#define atomic_spin_nop() asm ("rep; nop")


#define __arch_and_body(lock, mem, mask) \
Expand Down
2 changes: 1 addition & 1 deletion sysdeps/nacl/lll_timedwait_tid.c
Expand Up @@ -40,7 +40,7 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
finish quick enough that the timeout doesn't matter. If any
thread ever stays in this state for long, there is something
catastrophically wrong. */
BUSY_WAIT_NOP;
atomic_spin_nop ();
else
{
assert (tid > 0);
Expand Down
6 changes: 1 addition & 5 deletions sysdeps/nacl/lowlevellock.h
Expand Up @@ -21,10 +21,6 @@
/* Everything except the exit handling is the same as the generic code. */
# include <sysdeps/nptl/lowlevellock.h>

# ifndef BUSY_WAIT_NOP
# define BUSY_WAIT_NOP __sync_synchronize ()
# endif

/* See exit-thread.h for details. */
# define NACL_EXITING_TID 1

Expand All @@ -36,7 +32,7 @@
while ((__tid = atomic_load_relaxed (__tidp)) != 0) \
{ \
if (__tid == NACL_EXITING_TID) \
BUSY_WAIT_NOP; \
atomic_spin_nop (); \
else \
lll_futex_wait (__tidp, __tid, LLL_PRIVATE); \
} \
Expand Down
3 changes: 3 additions & 0 deletions sysdeps/sparc/sparc32/sparcv9/bits/atomic.h
Expand Up @@ -100,3 +100,6 @@ typedef uintmax_t uatomic_max_t;
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
#define atomic_write_barrier() \
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")

extern void __cpu_relax (void);
#define atomic_spin_nop () __cpu_relax ()
3 changes: 3 additions & 0 deletions sysdeps/sparc/sparc64/bits/atomic.h
Expand Up @@ -121,3 +121,6 @@ typedef uintmax_t uatomic_max_t;
__asm __volatile ("membar #LoadLoad | #LoadStore" : : : "memory")
#define atomic_write_barrier() \
__asm __volatile ("membar #LoadStore | #StoreStore" : : : "memory")

extern void __cpu_relax (void);
#define atomic_spin_nop () __cpu_relax ()
4 changes: 0 additions & 4 deletions sysdeps/unix/sysv/linux/i386/lowlevellock.h
Expand Up @@ -58,10 +58,6 @@
#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
after the cmpxchg instruction. In case the operation succeded this
value is zero. In case the operation failed, the cmpxchg instruction
Expand Down
6 changes: 0 additions & 6 deletions sysdeps/unix/sysv/linux/sparc/lowlevellock.h
Expand Up @@ -25,12 +25,6 @@
#include <atomic.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>

static inline int
Expand Down
3 changes: 0 additions & 3 deletions sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
Expand Up @@ -57,9 +57,6 @@
#define LLL_LOCK_INITIALIZER_LOCKED (1)
#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
after the cmpxchg instruction. In case the operation succeded this
Expand Down
2 changes: 1 addition & 1 deletion sysdeps/x86_64/bits/atomic.h
Expand Up @@ -410,7 +410,7 @@ typedef uintmax_t uatomic_max_t;
__result; })


#define atomic_delay() asm ("rep; nop")
#define atomic_spin_nop() asm ("rep; nop")


#define __arch_and_body(lock, mem, mask) \
Expand Down

0 comments on commit 4eb984d

Please sign in to comment.