diff options
author | Ivan Maidanski <ivmai@mail.ru> | 2018-03-14 01:18:30 +0300 |
---|---|---|
committer | Ivan Maidanski <ivmai@mail.ru> | 2018-03-14 01:18:30 +0300 |
commit | f282bb3502896b6740375465619c405e30780196 (patch) | |
tree | 0d4652f61a433a07f200230cb701ba4a1ef608ab /finalize.c | |
parent | eb4a25c70f8a1be9547dcb195c5c634bb3960b41 (diff) | |
download | bdwgc-f282bb3502896b6740375465619c405e30780196.tar.gz |
Access finalize_now atomically to avoid TSan warning without no-sanitize
* finalize.c (SET_FINALIZE_NOW): New macro (which uses AO_store if
available).
* finalize.c (GC_finalize): Use SET_FINALIZE_NOW(fo) instead of
GC_fnlz_roots.finalize_now=fo.
* finalize.c [!JAVA_FINALIZATION_NOT_NEEDED]
(GC_enqueue_all_finalizers): Likewise.
* finalize.c [THREADS] (GC_invoke_finalizers): Likewise.
* finalize.c (GC_should_invoke_finalizers): Remove
GC_ATTR_NO_SANITIZE_THREAD.
* finalize.c [AO_HAVE_load] (GC_should_invoke_finalizers): Use AO_load
to get GC_fnlz_roots.finalize_now value.
Diffstat (limited to 'finalize.c')
-rw-r--r-- | finalize.c | 25 |
1 files changed, 19 insertions, 6 deletions
@@ -78,6 +78,15 @@ STATIC struct fnlz_roots_s { struct finalizable_object *finalize_now; } GC_fnlz_roots = { NULL, NULL }; +#ifdef AO_HAVE_store + /* Update finalize_now atomically as GC_should_invoke_finalizers does */ + /* not acquire the allocation lock. */ +# define SET_FINALIZE_NOW(fo) \ + AO_store((volatile AO_t *)&GC_fnlz_roots.finalize_now, (AO_t)(fo)) +#else +# define SET_FINALIZE_NOW(fo) (void)(GC_fnlz_roots.finalize_now = (fo)) +#endif /* !THREADS */ + GC_API void GC_CALL GC_push_finalizer_structures(void) { GC_ASSERT((word)&GC_dl_hashtbl.head % sizeof(word) == 0); @@ -1017,7 +1026,7 @@ GC_INNER void GC_finalize(void) /* Add to list of objects awaiting finalization. */ fo_set_next(curr_fo, GC_fnlz_roots.finalize_now); - GC_fnlz_roots.finalize_now = curr_fo; + SET_FINALIZE_NOW(curr_fo); /* unhide object pointer so any future collections will */ /* see it. */ curr_fo -> fo_hidden_base = @@ -1067,7 +1076,7 @@ GC_INNER void GC_finalize(void) GC_set_mark_bit(real_ptr); } else { if (NULL == prev_fo) { - GC_fnlz_roots.finalize_now = next_fo; + SET_FINALIZE_NOW(next_fo); } else { fo_set_next(prev_fo, next_fo); } @@ -1133,7 +1142,7 @@ GC_INNER void GC_finalize(void) /* Add to list of objects awaiting finalization. */ fo_set_next(curr_fo, GC_fnlz_roots.finalize_now); - GC_fnlz_roots.finalize_now = curr_fo; + SET_FINALIZE_NOW(curr_fo); /* unhide object pointer so any future collections will */ /* see it. */ @@ -1184,10 +1193,13 @@ GC_INNER void GC_finalize(void) /* Returns true if it is worth calling GC_invoke_finalizers. (Useful if */ /* finalizers can only be called from some kind of "safe state" and */ /* getting into that safe state is expensive.) */ -GC_ATTR_NO_SANITIZE_THREAD GC_API int GC_CALL GC_should_invoke_finalizers(void) { - return GC_fnlz_roots.finalize_now != NULL; +# ifdef AO_HAVE_load + return AO_load((volatile AO_t *)&GC_fnlz_roots.finalize_now) != 0; +# else + return GC_fnlz_roots.finalize_now != NULL; +# endif /* !THREADS */ } /* Invoke finalizers for all objects that are ready to be finalized. */ @@ -1210,7 +1222,8 @@ GC_API int GC_CALL GC_invoke_finalizers(void) } curr_fo = GC_fnlz_roots.finalize_now; # ifdef THREADS - if (curr_fo != 0) GC_fnlz_roots.finalize_now = fo_next(curr_fo); + if (curr_fo != NULL) + SET_FINALIZE_NOW(fo_next(curr_fo)); UNLOCK(); if (curr_fo == 0) break; # else |