summaryrefslogtreecommitdiff
path: root/malloc.c
diff options
context:
space:
mode:
authorIvan Maidanski <ivmai@mail.ru>2017-11-16 01:15:14 +0300
committerIvan Maidanski <ivmai@mail.ru>2017-11-16 01:15:14 +0300
commite522d6d791680b55825b5f11a4c082eb4770ecf5 (patch)
tree36d644c42aa684b9a87d0e2d90b91fc6e62c271f /malloc.c
parent1e4e2cc93b5bead46518ce8028535492da662690 (diff)
downloadbdwgc-e522d6d791680b55825b5f11a4c082eb4770ecf5.tar.gz
Workaround TSan false positives in extend_size_map
Thread Sanitizer reports data races between fill_size_map (called from GC_extend_size_map) and GC_gcj_malloc[_ignore_off_page], GC_malloc_kind_global, GC_generic_malloc_uncollectable, GC_malloc_explicitly_typed_ignore_off_page which read a value from GC_size_map before acquiring the allocation lock. These races could be ignored as the value is verified after acquiring the lock. * alloc.c: Refine comment about GC_allocobj (and GC_size_map) usage for the case of a multi-threaded environment. * malloc.c (fill_size_map): New static function (with GC_ATTR_NO_SANITIZE_THREAD attribute). * malloc.c (GC_extend_size_map): Use fill_size_map() to fill in a region of GC_size_map.
Diffstat (limited to 'malloc.c')
-rw-r--r--malloc.c15
1 files changed, 13 insertions, 2 deletions
diff --git a/malloc.c b/malloc.c
index e1594e83..d2b2aeb7 100644
--- a/malloc.c
+++ b/malloc.c
@@ -102,6 +102,18 @@ STATIC ptr_t GC_alloc_large_and_clear(size_t lb, int k, unsigned flags)
return result;
}
+/* This function should be called with the allocation lock held. */
+/* At the same time, it is safe to get a value from GC_size_map not */
+/* acquiring the allocation lock provided the obtained value is used */
+/* according to the pattern given in alloc.c file (see the comment */
+/* about GC_allocobj usage and, e.g., GC_malloc_kind_global code). */
+static void fill_size_map(size_t low_limit, size_t byte_sz, size_t granule_sz)
+ GC_ATTR_NO_SANITIZE_THREAD
+{
+ for (; low_limit <= byte_sz; low_limit++)
+ GC_size_map[low_limit] = granule_sz;
+}
+
/* Fill in additional entries in GC_size_map, including the i-th one. */
/* Note that a filled in section of the array ending at n always */
/* has the length of at least n/4. */
@@ -151,8 +163,7 @@ STATIC void GC_extend_size_map(size_t i)
/* We may need one extra byte; do not always */
/* fill in GC_size_map[byte_sz]. */
- for (; low_limit <= byte_sz; low_limit++)
- GC_size_map[low_limit] = granule_sz;
+ fill_size_map(low_limit, byte_sz, granule_sz);
}
/* Allocate lb bytes for an object of kind k. */