From: Ivan Maidanski Date: Wed, 29 Nov 2017 17:15:49 +0000 (+0300) Subject: Fix data race in make_descriptor when setting explicit_typing_initialized X-Git-Tag: v7.6.2~22 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f262e4e9f986d11683c9ed10012e2b13f34625d;p=gc Fix data race in make_descriptor when setting explicit_typing_initialized (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). --- diff --git a/typd_mlc.c b/typd_mlc.c index d2ebf1a0..a7e814c6 100644 --- a/typd_mlc.c +++ b/typd_mlc.c @@ -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;