From 20468dd131d82be7422aea3c7383ec9201452fce Mon Sep 17 00:00:00 2001 From: Ivan Maidanski Date: Wed, 22 Nov 2017 01:05:13 +0300 Subject: [PATCH] Workaround TSan false positive about clear_hdr_marks/realloc data race * mallocx.c (hb_sz_async_grow_within_hblk): New static function (with GC_ATTR_NO_SANITIZE_THREAD attribute). * mallocx.c (GC_realloc): Call hb_sz_async_grow_within_hblk instead of hhdr->hb_sz=sz. --- mallocx.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/mallocx.c b/mallocx.c index 7831b38..a38653c 100644 --- a/mallocx.c +++ b/mallocx.c @@ -78,6 +78,18 @@ GC_API GC_ATTR_MALLOC void * GC_CALL GC_generic_or_special_malloc(size_t lb, } } +/* There could be a data race between this function (called from */ +/* GC_realloc without any synchronization) and e.g. GC_clear_hdr_marks */ +/* (invoked indirectly from GC_try_to_collect_inner) but it should be */ +/* safe as long as the new size is not smaller than the old one. */ +GC_ATTR_NO_SANITIZE_THREAD +static void hb_sz_async_grow_within_hblk(hdr * hhdr, size_t sz) +{ + GC_ASSERT(hhdr->hb_sz <= sz + && sz <= ((hhdr->hb_sz + HBLKSIZE - 1) & ~HBLKMASK)); + hhdr->hb_sz = sz; +} + /* Change the size of the block pointed to by p to contain at least */ /* lb bytes. The object may be (and quite likely will be) moved. */ /* The kind (e.g. atomic) is the same as that of the old. */ @@ -109,7 +121,7 @@ GC_API void * GC_CALL GC_realloc(void * p, size_t lb) word descr; sz = (sz+HBLKSIZE-1) & (~HBLKMASK); - hhdr -> hb_sz = sz; + hb_sz_async_grow_within_hblk(hhdr, sz); descr = GC_obj_kinds[obj_kind].ok_descriptor; if (GC_obj_kinds[obj_kind].ok_relocate_descr) descr += sz; hhdr -> hb_descr = descr; -- 2.7.4