Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVlad Brezae <brezaevlad@gmail.com>2015-09-15 01:39:03 +0300
committerAlexis Christoforides <alexis@thenull.net>2016-01-20 02:35:54 +0300
commit996df3cb3b06afacf75adabfc63223b3e2471498 (patch)
tree0a9d12d2c25058c6047c59861e424f5b18eed8f8
parentefae6a06ef2318e8d9eb0fb62ae349adbc399704 (diff)
[sgen] Fix race between block allocation and concurrent sweep.mono-4.2.2.30mono-4.2.0-branch-c6sr1
Adding a new block to the allocated_blocks array is racy with the removal of nulls when sweeping. We wait for sweep to finish to avoid that. This also handles the problem of allocating degraded objects while sweeping.
-rw-r--r--mono/sgen/sgen-marksweep.c13
1 files changed, 4 insertions, 9 deletions
diff --git a/mono/sgen/sgen-marksweep.c b/mono/sgen/sgen-marksweep.c
index 0cd42f7a79f..55f40aba76e 100644
--- a/mono/sgen/sgen-marksweep.c
+++ b/mono/sgen/sgen-marksweep.c
@@ -559,17 +559,14 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
add_free_block (free_blocks, size_index, info);
/*
- * This is the only place where the `allocated_blocks` array can potentially grow.
- * We need to make sure concurrent sweep isn't running when that happens, so in that
- * specific case we just wait for sweep to finish.
+ * Adding to the allocated_blocks array is racy with the removal of nulls when
+ * sweeping. We wait for sweep to finish to avoid that.
*
* The memory barrier here and in `sweep_job_func()` are required because we need
* `allocated_blocks` synchronized between this and the sweep thread.
*/
- if (sgen_pointer_queue_will_grow (&allocated_blocks)) {
- major_finish_sweep_checking ();
- mono_memory_barrier ();
- }
+ major_finish_sweep_checking ();
+ mono_memory_barrier ();
sgen_pointer_queue_add (&allocated_blocks, BLOCK_TAG (info));
@@ -746,8 +743,6 @@ major_alloc_degraded (GCVTable vtable, size_t size)
{
GCObject *obj;
- major_finish_sweep_checking ();
-
obj = alloc_obj (vtable, size, FALSE, SGEN_VTABLE_HAS_REFERENCES (vtable));
if (G_LIKELY (obj)) {
HEAVY_STAT (++stat_objects_alloced_degraded);