]> 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>
Tue, 20 Nov 2018 21:19:20 +0000 (00:19 +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 7db06459de003ac7849387ffad0e65cb589a2b9e..0fd566635a6b9a5c12c5ee225a4a21f34afc0c39 100644 (file)
@@ -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;
index ef982d51d899d0fb622c27b0591aa38c00a38695..235f2c8643fc92afd3a8cbf1fa425f55938d221a 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 8f2222c911f9ca9f3af5d1fdf0ea7a64c9535f67..949f1f640eca74a87b451a306abb77de3276c35f 100644 (file)
@@ -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
index dd6160039f7bd3884ebc850d44653c6cb831d09e..57cda3e242925164e364948eb6b6f09b521816b2 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)