]> granicus.if.org Git - gc/commitdiff
Fix a deadlock in write_fault_handler if AO_or is emulated
authorIvan Maidanski <ivmai@mail.ru>
Tue, 20 Nov 2018 21:19:20 +0000 (00:19 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Mon, 26 Nov 2018 06:06:54 +0000 (09:06 +0300)
* 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).

configure.ac
include/private/gc_atomic_ops.h
include/private/gc_priv.h
os_dep.c

index af63416b132cef4bbaca34d665b73db317a23d51..abe944123eb41170b71f621e774dc0011ce53e8b 100644 (file)
@@ -1108,6 +1108,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;
index 776d4551905426528744c9b27b7de37e4709802b..68f8b4754357b0d5aa00250903edbd1de04d06cc 100644 (file)
     } /* 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"
index 32f0b8573746583d4ca7ef135d34cad0baa643f9..011057745b2aeb90bb179fca7ae3d598144e29e0 100644 (file)
@@ -2319,7 +2319,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
index 263e462cd54dc0b9511803b8abeb0722d63292a8..2f9dabc21d40fc1eb03f96be1cfbf723b8eedeae 100644 (file)
--- 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)