]> granicus.if.org Git - gc/commitdiff
Fix data race in make_descriptor when setting explicit_typing_initialized
authorIvan Maidanski <ivmai@mail.ru>
Wed, 29 Nov 2017 17:15:49 +0000 (20:15 +0300)
committerIvan Maidanski <ivmai@mail.ru>
Fri, 15 Dec 2017 17:59:40 +0000 (20:59 +0300)
(fix commit 5f350a0)

* typd_mlc.c [AO_HAVE_load_acquire] (GC_explicit_typing_initialized):
Add volatile qualifier.
* typd_mlc.c [AO_HAVE_load_acquire] (GC_make_descriptor): Remove
cast of &GC_explicit_typing_initialized; do not check THREADS macro;
fallback to locked checking of GC_explicit_typing_initialized if
AO_HAVE_store_release is not defined; use AO_store_release to set
GC_explicit_typing_initialized (to true).
* typd_mlc.c (GC_make_descriptor): Reformat code dealing with
GC_explicit_typing_initialized (check whether AO_HAVE_load_acquire is
defined only once).

typd_mlc.c

index d2ebf1a0f32cd669f5a32f8d75a7057f1618d432..a7e814c6fabfdd6e051d83f1a8997bcaf87ef2c3 100644 (file)
@@ -103,13 +103,11 @@ STATIC int GC_array_mark_proc_index = 0; /* procedures.                 */
 # include "atomic_ops.h"
 #endif
 
-STATIC
-# ifdef AO_HAVE_load_acquire
-    AO_t
-# else
-    GC_bool
-# endif
-  GC_explicit_typing_initialized = FALSE;
+#ifdef AO_HAVE_load_acquire
+  STATIC volatile AO_t GC_explicit_typing_initialized = FALSE;
+#else
+  STATIC GC_bool GC_explicit_typing_initialized = FALSE;
+#endif
 
 STATIC void GC_push_typed_structures_proc(void)
 {
@@ -528,28 +526,28 @@ GC_API GC_descr GC_CALL GC_make_descriptor(const GC_word * bm, size_t len)
 #   define HIGH_BIT (((word)1) << (WORDSZ - 1))
     DCL_LOCK_STATE;
 
-#   if defined(THREADS) && defined(AO_HAVE_load_acquire)
-      if (!EXPECT(AO_load_acquire(
-                        (volatile AO_t *)&GC_explicit_typing_initialized),
-                  TRUE))
-#   endif
-    {
+#   if defined(AO_HAVE_load_acquire) && defined(AO_HAVE_store_release)
+      if (!EXPECT(AO_load_acquire(&GC_explicit_typing_initialized), TRUE)) {
+        LOCK();
+        if (!GC_explicit_typing_initialized) {
+          GC_init_explicit_typing();
+          AO_store_release(&GC_explicit_typing_initialized, TRUE);
+        }
+        UNLOCK();
+      }
+#   else
       LOCK();
-#     if defined(THREADS) && defined(AO_HAVE_load_acquire)
-        if (!GC_explicit_typing_initialized)
-#     else
-        if (!EXPECT(GC_explicit_typing_initialized, TRUE))
-#     endif
-      {
+      if (!EXPECT(GC_explicit_typing_initialized, TRUE)) {
         GC_init_explicit_typing();
         GC_explicit_typing_initialized = TRUE;
       }
       UNLOCK();
-    }
+#   endif
 
     while (last_set_bit >= 0 && !GC_get_bit(bm, last_set_bit))
       last_set_bit--;
     if (last_set_bit < 0) return(0 /* no pointers */);
+
 #   if ALIGNMENT == CPP_WORDSZ/8
     {
       signed_word i;