diff options
| author | Lennart Poettering <lennart@poettering.net> | 2009-05-19 22:30:14 +0200 | 
|---|---|---|
| committer | Lennart Poettering <lennart@poettering.net> | 2009-05-20 02:09:32 +0200 | 
| commit | 9293e823767daee79386cc797510808f4eed01a3 (patch) | |
| tree | b1f482f0cdf51c1ef2d78931665db6a7175502a8 | |
| parent | 74bff5af804817372aece931c792b53c8ec534e1 (diff) | |
atomic: implement atomic operations based on gcc's __sync extension
Newer gccs and intel ccs support a __sync extension for making use of
atomic operations. This patch replaces the handcrafted x86 atomic
operation support with usage of __sync.
__sync is supported by more processors and by more compilers than the
old assembler code. Also, this extension has been available on gcc for
quite a while now for x86, so replacing the old assembler code should
only be a loss when very old compiilers are used.
| -rw-r--r-- | configure.in | 50 | ||||
| -rw-r--r-- | dbus/dbus-internals.h | 9 | ||||
| -rw-r--r-- | dbus/dbus-sysdeps-unix.c | 29 | ||||
| -rw-r--r-- | dbus/dbus-threads.c | 2 | 
4 files changed, 30 insertions, 60 deletions
diff --git a/configure.in b/configure.in index b087b003..c2c6a8c9 100644 --- a/configure.in +++ b/configure.in @@ -590,41 +590,23 @@ if test "x$dbus_cv_va_val_copy" = "xno"; then  fi -#### Atomic integers (checks by Sebastian Wilhelmi for GLib) -AC_MSG_CHECKING([whether to use inline assembler routines for atomic integers]) -have_atomic_inc_cond=0 -if test x"$GCC" = xyes; then -  if test "x$enable_ansi" = "xyes"; then -    AC_MSG_RESULT([no]) -  else -    case $host_cpu in -      i386) -        AC_MSG_RESULT([no]) -        ;; -      i?86) -        case $host_os in -          darwin*) -            AC_MSG_RESULT([darwin]) -            # check at compile-time, so that it is possible to build universal -            # (with multiple architectures at once on the compile line) -            have_atomic_inc_cond="(defined(__i386__) || defined(__x86_64__))" -            ;; -          *) -            AC_MSG_RESULT([i486]) -            have_atomic_inc_cond=1 -            ;; -        esac -        ;; -      *) -        AC_MSG_RESULT([no]) -        ;; -    esac -  fi +#### Atomic integers + +AC_CACHE_CHECK([whether $CC knows __sync_sub_and_fetch()], +  dbus_cv_sync_sub_and_fetch, +  [AC_LINK_IFELSE( +     AC_LANG_PROGRAM([], [[int a = 4; __sync_sub_and_fetch(&a, 4);]]), +     [dbus_cv_sync_sub_and_fetch=yes], +     [dbus_cv_sync_sub_and_fetch=no]) +  ]) + +if test "x$dbus_cv_sync_sub_and_fetch" = "xyes" ; then +   have_sync=1 +else +   have_sync=0  fi -AC_DEFINE_UNQUOTED([DBUS_USE_ATOMIC_INT_486_COND], [$have_atomic_inc_cond], -                   [Always defined; expands to 1 if we should use atomic integer implementation for 486, else 0]) -AC_DEFINE_UNQUOTED(DBUS_HAVE_ATOMIC_INT_COND, [$have_atomic_inc_cond], -                   [Always defined; expands to 1 if we have an atomic integer implementation, else 0]) + +AC_DEFINE_UNQUOTED([DBUS_USE_SYNC], [$have_sync], [Use the gcc __sync extension])  #### Various functions  AC_CHECK_LIB(socket,socket) diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h index 3e5f989d..835fe46a 100644 --- a/dbus/dbus-internals.h +++ b/dbus/dbus-internals.h @@ -294,18 +294,23 @@ _DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots);  _DBUS_DECLARE_GLOBAL_LOCK (server_slots);  _DBUS_DECLARE_GLOBAL_LOCK (message_slots);  /* 5-10 */ -_DBUS_DECLARE_GLOBAL_LOCK (atomic);  _DBUS_DECLARE_GLOBAL_LOCK (bus);  _DBUS_DECLARE_GLOBAL_LOCK (bus_datas);  _DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs);  _DBUS_DECLARE_GLOBAL_LOCK (system_users); -/* 10-15 */  _DBUS_DECLARE_GLOBAL_LOCK (message_cache); +/* 10-14 */  _DBUS_DECLARE_GLOBAL_LOCK (shared_connections);  _DBUS_DECLARE_GLOBAL_LOCK (win_fds);  _DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache);  _DBUS_DECLARE_GLOBAL_LOCK (machine_uuid); + +#if !DBUS_USE_SYNC +_DBUS_DECLARE_GLOBAL_LOCK (atomic);  #define _DBUS_N_GLOBAL_LOCKS (15) +#else +#define _DBUS_N_GLOBAL_LOCKS (14) +#endif  dbus_bool_t _dbus_threads_init_debug (void); diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 07db1c5f..42aa9674 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2180,23 +2180,8 @@ _dbus_parse_uid (const DBusString      *uid_str,    return TRUE;  } - +#if !DBUS_USE_SYNC  _DBUS_DEFINE_GLOBAL_LOCK (atomic); - -#if DBUS_USE_ATOMIC_INT_486_COND -/* Taken from CVS version 1.7 of glibc's sysdeps/i386/i486/atomicity.h */ -/* Since the asm stuff here is gcc-specific we go ahead and use "inline" also */ -static inline dbus_int32_t -atomic_exchange_and_add (DBusAtomic            *atomic, -                         volatile dbus_int32_t  val) -{ -  register dbus_int32_t result; - -  __asm__ __volatile__ ("lock; xaddl %0,%1" -                        : "=r" (result), "=m" (atomic->value) -			: "0" (val), "m" (atomic->value)); -  return result; -}  #endif  /** @@ -2204,14 +2189,12 @@ atomic_exchange_and_add (DBusAtomic            *atomic,   *   * @param atomic pointer to the integer to increment   * @returns the value before incrementing - * - * @todo implement arch-specific faster atomic ops   */  dbus_int32_t  _dbus_atomic_inc (DBusAtomic *atomic)  { -#if DBUS_USE_ATOMIC_INT_486_COND -  return atomic_exchange_and_add (atomic, 1); +#if DBUS_USE_SYNC +  return __sync_add_and_fetch(&atomic->value, 1)-1;  #else    dbus_int32_t res;    _DBUS_LOCK (atomic); @@ -2227,14 +2210,12 @@ _dbus_atomic_inc (DBusAtomic *atomic)   *   * @param atomic pointer to the integer to decrement   * @returns the value before decrementing - * - * @todo implement arch-specific faster atomic ops   */  dbus_int32_t  _dbus_atomic_dec (DBusAtomic *atomic)  { -#if DBUS_USE_ATOMIC_INT_486_COND -  return atomic_exchange_and_add (atomic, -1); +#if DBUS_USE_SYNC +  return __sync_sub_and_fetch(&atomic->value, 1)+1;  #else    dbus_int32_t res; diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c index 00c1a4b1..cb9c7237 100644 --- a/dbus/dbus-threads.c +++ b/dbus/dbus-threads.c @@ -424,7 +424,9 @@ init_locks (void)      LOCK_ADDR (pending_call_slots),      LOCK_ADDR (server_slots),      LOCK_ADDR (message_slots), +#if !DBUS_USE_SYNC      LOCK_ADDR (atomic), +#endif      LOCK_ADDR (bus),      LOCK_ADDR (bus_datas),      LOCK_ADDR (shutdown_funcs),  | 
