diff options
author | Vlad Brezae <brezaevlad@gmail.com> | 2015-09-15 01:39:03 +0300 |
---|---|---|
committer | Alexis Christoforides <alexis@thenull.net> | 2016-01-20 02:35:54 +0300 |
commit | 996df3cb3b06afacf75adabfc63223b3e2471498 (patch) | |
tree | 0a9d12d2c25058c6047c59861e424f5b18eed8f8 | |
parent | efae6a06ef2318e8d9eb0fb62ae349adbc399704 (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.c | 13 |
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); |