mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-08-22 17:08:53 +02:00
gatomic: introduce G_ATOMIC_LOCK_FREE
We clean up the detection of if we should do 'real' atomic operations or mutex-emulated ones with the introduction of a new (public) macro: G_ATOMIC_LOCK_FREE. If defined, our atomic operations are guaranteed to be done in hardware. We need to use __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 to determine if our compiler supports GCC-style atomic operations from the gatomic.h header because we might be building a program against GLib using a different set of compiler options (or a different compiler) than was used to build GLib itself. Unfortunately, this macro is not available on clang, so it has currently regressed to using the mutex emulation. A bug about that has been opened here: http://llvm.org/bugs/show_bug.cgi?id=11174
This commit is contained in:
77
configure.ac
77
configure.ac
@@ -2407,35 +2407,58 @@ dnl ************************
|
||||
dnl *** g_atomic_* tests ***
|
||||
dnl ************************
|
||||
|
||||
case $host_cpu in
|
||||
i?86|x86_64|s390|s390x|arm*|crisv32*|etrax*)
|
||||
glib_memory_barrier_needed=no
|
||||
;;
|
||||
sparc*|alpha*|powerpc*|ia64)
|
||||
glib_memory_barrier_needed=yes
|
||||
;;
|
||||
*)
|
||||
glib_memory_barrier_needed=yes
|
||||
;;
|
||||
esac
|
||||
dnl We need to decide at configure time if GLib will use real atomic
|
||||
dnl operations ("lock free") or emulated ones with a mutex. This is
|
||||
dnl because we must put this information in glibconfig.h so we know if
|
||||
dnl it is safe or not to inline using compiler intrinsics directly from
|
||||
dnl the header.
|
||||
dnl
|
||||
dnl We also publish the information via G_ATOMIC_LOCK_FREE in case the
|
||||
dnl user is interested in knowing if they can use the atomic ops across
|
||||
dnl processes.
|
||||
dnl
|
||||
dnl We can currently support the atomic ops natively when building GLib
|
||||
dnl with recent versions of GCC or MSVC. MSVC doesn't run ./configure,
|
||||
dnl so we skip that case here and define G_ATOMIC_LOCK_FREE exactly when
|
||||
dnl we are using GCC.
|
||||
dnl
|
||||
dnl Note that the atomic ops are only available with GCC on x86 when
|
||||
dnl using -march=i486 or higher. If we detect that the atomic ops are
|
||||
dnl not available but would be available given the right flags, we want
|
||||
dnl to abort and advise the user to fix their CFLAGS. It's better to do
|
||||
dnl that then to silently fall back on emulated atomic ops just because
|
||||
dnl the user had the wrong build environment.
|
||||
|
||||
glib_cv_gcc_has_builtin_atomic_operations=no
|
||||
if test x"$GCC" = xyes; then
|
||||
AC_MSG_CHECKING([whether GCC supports built-in atomic intrinsics])
|
||||
AC_TRY_LINK([],
|
||||
[int i;
|
||||
__sync_synchronize ();
|
||||
__sync_bool_compare_and_swap (&i, 0, 1);
|
||||
__sync_fetch_and_add (&i, 1);
|
||||
],
|
||||
[glib_cv_gcc_has_builtin_atomic_operations=yes],
|
||||
[glib_cv_gcc_has_builtin_atomic_operations=no])
|
||||
dnl We may add other compilers here in the future...
|
||||
AC_MSG_CHECKING([for lock-free atomic intrinsics])
|
||||
AC_TRY_COMPILE([],
|
||||
[__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;],
|
||||
[g_atomic_lock_free=yes],
|
||||
[g_atomic_lock_free=no])
|
||||
AC_MSG_RESULT($g_atomic_lock_free)
|
||||
|
||||
AC_MSG_RESULT($glib_cv_gcc_has_builtin_atomic_operations)
|
||||
if test "$g_atomic_lock_free" = "no"; then
|
||||
SAVE_CFLAGS="${CFLAGS}"
|
||||
CFLAGS="-march=i486"
|
||||
AC_TRY_COMPILE([],
|
||||
[__GCC_HAVE_SYNC_COMPARE_AND_SWAP_4;],
|
||||
[AC_MSG_ERROR([GLib must be build with -march=i486 or later.])],
|
||||
[])
|
||||
CFLAGS="${SAVE_CFLAGS}"
|
||||
fi
|
||||
|
||||
AM_CONDITIONAL(HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS,
|
||||
[test $glib_cv_gcc_has_builtin_atomic_operations = yes])
|
||||
dnl We need a more robust approach here...
|
||||
case $host_cpu in
|
||||
i?86|x86_64|s390|s390x|arm*|crisv32*|etrax*)
|
||||
glib_memory_barrier_needed=no
|
||||
;;
|
||||
sparc*|alpha*|powerpc*|ia64)
|
||||
glib_memory_barrier_needed=yes
|
||||
;;
|
||||
*)
|
||||
glib_memory_barrier_needed=yes
|
||||
;;
|
||||
esac
|
||||
|
||||
dnl ************************
|
||||
dnl ** Check for futex(2) **
|
||||
@@ -3085,9 +3108,9 @@ _______EOF
|
||||
echo >>$outfile
|
||||
echo "#define G_ATOMIC_OP_MEMORY_BARRIER_NEEDED 1" >>$outfile
|
||||
fi
|
||||
if test x"$g_gcc_atomic_ops" != xno; then
|
||||
if test x"$g_atomic_lock_free" = xyes; then
|
||||
echo >>$outfile
|
||||
echo "#define G_ATOMIC_OP_USE_GCC_BUILTINS 1" >>$outfile
|
||||
echo "#define G_ATOMIC_LOCK_FREE" >>$outfile
|
||||
fi
|
||||
echo >>$outfile
|
||||
g_bit_sizes="16 32 64"
|
||||
|
Reference in New Issue
Block a user