From: Ivan Maidanski Date: Tue, 21 Nov 2017 22:05:13 +0000 (+0300) Subject: Workaround TSan false positive about clear_hdr_marks/realloc data race X-Git-Tag: v8.0.0~500 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=20468dd131d82be7422aea3c7383ec9201452fce;p=gc 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. --- diff --git a/mallocx.c b/mallocx.c index 7831b387..a38653c9 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;