Commit 9293e823 authored by Lennart Poettering's avatar Lennart Poettering

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.
parent 74bff5af
......@@ -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)
......
......@@ -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);
......
......@@ -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;
......
......@@ -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),
......
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