summaryrefslogtreecommitdiff
path: root/finalize.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-03-14 01:18:30 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-03-14 01:18:30 +0300
commitf282bb3502896b6740375465619c405e30780196 (patch)
tree0d4652f61a433a07f200230cb701ba4a1ef608ab /finalize.c
parenteb4a25c70f8a1be9547dcb195c5c634bb3960b41 (diff)
downloadbdwgc-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.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/finalize.c b/finalize.c
index 6f178b9d..10d9b9e4 100644
--- a/finalize.c
+++ b/finalize.c
@@ -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