summaryrefslogtreecommitdiff
path: root/mallocx.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2021-07-29 09:13:05 +0300
committerIvan Maidanski <ivmai@mail.ru>2021-07-29 13:20:04 +0300
commitdcaad02116999a1ebb28707d301dd220f7e96005 (patch)
treec7744a40f80ea7c55a0bd5a257f91fe822c5192b /mallocx.c
parentd0ba209660ea8c663e06d9a68332ba5f42da54ba (diff)
downloadbdwgc-dcaad02116999a1ebb28707d301dd220f7e96005.tar.gz
Fix data race regarding *rlh value in generic_malloc_many
The issue was highlighted in GC_generic_malloc_many() by a static code analysis tool as "using an unreliable value of *rlh inside the second locked section; if the data that *rlh depends on was changed by another thread, this use might be incorrect". * mallocx.c (GC_generic_malloc_many): Do not increment rlh by lg (use rlh[lg] instead); change for statement to while; reload rlh value after acquiring the GC lock (at the end of the loop).
Diffstat (limited to 'mallocx.c')
-rw-r--r--mallocx.c7
1 files changed, 5 insertions, 2 deletions
diff --git a/mallocx.c b/mallocx.c
index 216ffdc2..3106819b 100644
--- a/mallocx.c
+++ b/mallocx.c
@@ -343,9 +343,9 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
struct hblk * hbp;
hdr * hhdr;
- for (rlh += lg; (hbp = *rlh) != NULL; ) {
+ while ((hbp = rlh[lg]) != NULL) {
hhdr = HDR(hbp);
- *rlh = hhdr -> hb_next;
+ rlh[lg] = hhdr -> hb_next;
GC_ASSERT(hhdr -> hb_sz == lb);
hhdr -> hb_last_reclaimed = (unsigned short) GC_gc_no;
# ifdef PARALLEL_MARK
@@ -409,6 +409,9 @@ GC_API void GC_CALL GC_generic_malloc_many(size_t lb, int k, void **result)
/* GC lock is needed for reclaim list access. We */
/* must decrement fl_builder_count before reacquiring */
/* the lock. Hopefully this path is rare. */
+
+ rlh = ok -> ok_reclaim_list; /* reload rlh after locking */
+ if (NULL == rlh) break;
}
# endif
}