From: Ivan Maidanski Date: Tue, 20 Nov 2018 21:19:20 +0000 (+0300) Subject: Fix a deadlock in write_fault_handler if AO_or is emulated X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=016f30060f3c34a69387fa64e1f75f69057d57c0;p=gc Fix a deadlock in write_fault_handler if AO_or is emulated * configure.ac [$with_libatomic_ops!=none && $need_atomic_ops_asm!=true] (HAVE_LOCKFREE_AO_OR): New AC_DEFINE (defined in case of success of AC_TRY_LINK of a code snippet calling AO_or). * include/private/gc_atomic_ops.h [GC_BUILTIN_ATOMIC && !NO_LOCKFREE_AO_OR] (HAVE_LOCKFREE_AO_OR): Define (to 1). * include/private/gc_priv.h [THREADS] (GC_acquire_dirty_lock, GC_release_dirty_lock): Define to no-op only if HAVE_LOCKFREE_AO_OR or GC_DISABLE_INCREMENTAL. * os_dep.c [!GC_DISABLE_INCREMENTAL] (async_set_pht_entry_from_index): Use set_pht_entry_from_index_concurrent() only if HAVE_LOCKFREE_AO_OR (or not THREADS). --- diff --git a/configure.ac b/configure.ac index 7db06459..0fd56663 100644 --- a/configure.ac +++ b/configure.ac @@ -1109,6 +1109,13 @@ AM_CONDITIONAL([NEED_ATOMIC_OPS_ASM], AS_IF([test x$with_libatomic_ops != xnone -a x$need_atomic_ops_asm != xtrue], [ old_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS $AO_TRYLINK_CFLAGS $CFLAGS_EXTRA" + AC_MSG_CHECKING([for lock-free AO_or primitive]) + AC_TRY_LINK([#include "atomic_ops.h"], + [AO_t x=0;AO_or(&x,1)], + [ AC_MSG_RESULT(yes) + AC_DEFINE([HAVE_LOCKFREE_AO_OR], [1], + [libatomic_ops AO_or primitive implementation is lock-free.]) ], + [ AC_MSG_RESULT(no) ]) AC_MSG_CHECKING([for lock-free AO load/store, test-and-set primitives]) AC_TRY_LINK([#include "atomic_ops.h"], [AO_t x=0;unsigned char c=0;AO_TS_t z=AO_TS_INITIALIZER; diff --git a/include/private/gc_atomic_ops.h b/include/private/gc_atomic_ops.h index ef982d51..235f2c86 100644 --- a/include/private/gc_atomic_ops.h +++ b/include/private/gc_atomic_ops.h @@ -100,6 +100,11 @@ } /* extern "C" */ # endif +# ifndef NO_LOCKFREE_AO_OR + /* __atomic_or_fetch is assumed to be lock-free. */ +# define HAVE_LOCKFREE_AO_OR 1 +# endif + #else /* Fallback to libatomic_ops. */ # include "atomic_ops.h" diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 8f2222c9..949f1f64 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -2313,7 +2313,7 @@ GC_EXTERN signed_word GC_bytes_found; /* protected by GC_write_cs. */ # endif -# if defined(GC_DISABLE_INCREMENTAL) || defined(AO_HAVE_or) +# if defined(GC_DISABLE_INCREMENTAL) || defined(HAVE_LOCKFREE_AO_OR) # define GC_acquire_dirty_lock() (void)0 # define GC_release_dirty_lock() (void)0 # else diff --git a/os_dep.c b/os_dep.c index dd616003..57cda3e2 100644 --- a/os_dep.c +++ b/os_dep.c @@ -2959,7 +2959,7 @@ GC_API GC_push_other_roots_proc GC_CALL GC_get_push_other_roots(void) #endif /* DEFAULT_VDB */ #ifndef GC_DISABLE_INCREMENTAL -# if !defined(THREADS) || defined(AO_HAVE_or) +# if !defined(THREADS) || defined(HAVE_LOCKFREE_AO_OR) # define async_set_pht_entry_from_index(db, index) \ set_pht_entry_from_index_concurrent(db, index) # elif defined(AO_HAVE_test_and_set_acquire)