summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2022-05-09 09:51:07 +0300
committerIvan Maidanski <ivmai@mail.ru>2022-05-09 09:51:07 +0300
commit3fb898c63826fe87eb9c6a998c5ccb79378777c0 (patch)
tree3c188d62e59cc1b258fef148b061f32f3007e237
parentfc40e2e41d1788b2a7c030cf033de38e7625a38c (diff)
downloadbdwgc-3fb898c63826fe87eb9c6a998c5ccb79378777c0.tar.gz
Make finalizer_closure pointer read/write atomic in malloc and callback
* fnlz_mlc.c [AO_HAVE_load] (GC_finalized_disclaim): Use AO_load() to read the 1st word of obj. * fnlz_mlc.c (GC_finalized_malloc): Change type of op local variable from word* to void*. * fnlz_mlc.c [AO_HAVE_store] (GC_finalized_malloc): Use AO_store() to write the 1st word of obj.
-rw-r--r--fnlz_mlc.c19
1 files changed, 13 insertions, 6 deletions
diff --git a/fnlz_mlc.c b/fnlz_mlc.c
index 9aee3ca3..06d0fb84 100644
--- a/fnlz_mlc.c
+++ b/fnlz_mlc.c
@@ -29,7 +29,11 @@
STATIC int GC_CALLBACK GC_finalized_disclaim(void *obj)
{
- word fc_word = *(word *)obj;
+# ifdef AO_HAVE_load
+ word fc_word = (word)AO_load((volatile AO_t *)obj);
+# else
+ word fc_word = *(word *)obj;
+# endif
if ((fc_word & FINALIZER_CLOSURE_FLAG) != 0) {
/* The disclaim function may be passed fragments from the */
@@ -94,19 +98,22 @@ GC_API void GC_CALL GC_register_disclaim_proc(int kind, GC_disclaim_proc proc,
GC_API GC_ATTR_MALLOC void * GC_CALL GC_finalized_malloc(size_t lb,
const struct GC_finalizer_closure *fclos)
{
- word *op;
+ void *op;
GC_ASSERT(GC_finalized_kind != 0);
GC_ASSERT(NONNULL_ARG_NOT_NULL(fclos));
GC_ASSERT(((word)fclos & FINALIZER_CLOSURE_FLAG) == 0);
- op = (word *)GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)),
- GC_finalized_kind);
+ op = GC_malloc_kind(SIZET_SAT_ADD(lb, sizeof(word)), GC_finalized_kind);
if (EXPECT(NULL == op, FALSE))
return NULL;
- *op = (word)fclos | FINALIZER_CLOSURE_FLAG;
+# ifdef AO_HAVE_store
+ AO_store((volatile AO_t *)op, (AO_t)fclos | FINALIZER_CLOSURE_FLAG);
+# else
+ *(word *)op = (word)fclos | FINALIZER_CLOSURE_FLAG;
+# endif
GC_dirty(op);
REACHABLE_AFTER_DIRTY(fclos);
- return op + 1;
+ return (word *)op + 1;
}
#endif /* ENABLE_DISCLAIM */