summaryrefslogtreecommitdiff
path: root/thread_local_alloc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2018-03-23 21:29:28 +0300
committerIvan Maidanski <ivmai@mail.ru>2018-03-23 21:32:44 +0300
commiteffa229cd92c83abef1180155d48cd5e69f439f1 (patch)
tree966edb9606694e71a1d95f63567cf20c09d75c10 /thread_local_alloc.c
parent877e5ea565b7afd1890f33c89c3cff148ccd32a6 (diff)
downloadbdwgc-effa229cd92c83abef1180155d48cd5e69f439f1.tar.gz
Avoid potential race between malloc_kind and mark_thread_local_fls_for
Issue #214 (bdwgc). * include/gc_inline.h (GC_FAST_M_AO_STORE): New internal macro. * include/gc_inline.h (GC_FAST_MALLOC_GRANS): Use GC_FAST_M_AO_STORE. * thread_local_alloc.c [THREAD_LOCAL_ALLOC] (GC_mark_thread_local_fls_for): Use AO_load to get _freelists[i][j] value; add comment. * thread_local_alloc.c [THREAD_LOCAL_ALLOC && GC_GCJ_SUPPORT] (GC_mark_thread_local_fls_for): Use AO_load to get gcj_freelists[j].
Diffstat (limited to 'thread_local_alloc.c')
-rw-r--r--thread_local_alloc.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/thread_local_alloc.c b/thread_local_alloc.c
index aaebd3a8..3a04fbe8 100644
--- a/thread_local_alloc.c
+++ b/thread_local_alloc.c
@@ -266,13 +266,15 @@ GC_INNER void GC_mark_thread_local_fls_for(GC_tlfs p)
for (j = 0; j < TINY_FREELISTS; ++j) {
for (i = 0; i < THREAD_FREELISTS_KINDS; ++i) {
- q = (ptr_t)p->_freelists[i][j];
+ /* Load the pointer atomically as it might be updated */
+ /* concurrently by GC_FAST_MALLOC_GRANS. */
+ q = (ptr_t)AO_load((volatile AO_t *)&p->_freelists[i][j]);
if ((word)q > HBLKSIZE)
GC_set_fl_marks(q);
}
# ifdef GC_GCJ_SUPPORT
if (EXPECT(j > 0, TRUE)) {
- q = (ptr_t)p->gcj_freelists[j];
+ q = (ptr_t)AO_load((volatile AO_t *)&p->gcj_freelists[j]);
if ((word)q > HBLKSIZE)
GC_set_fl_marks(q);
}