[sgen] Properly synchronize `allocated_blocks`.
authorMark Probst <mark.probst@gmail.com>
Tue, 1 Sep 2015 22:02:40 +0000 (15:02 -0700)
committerMark Probst <mark.probst@gmail.com>
Tue, 1 Sep 2015 22:04:30 +0000 (15:04 -0700)
We were missing a memory barrier here.  This might fix the current
intermittent crashes on wrench.

mono/sgen/sgen-marksweep.c

index 96444b1dc60d066f17aaf60924ba950538269c7a..0cd42f7a79f405233430a80d78083265c5021c9c 100644 (file)
@@ -562,9 +562,14 @@ ms_alloc_block (int size_index, gboolean pinned, gboolean has_references)
         * 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.
+        *
+        * 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))
+       if (sgen_pointer_queue_will_grow (&allocated_blocks)) {
                major_finish_sweep_checking ();
+               mono_memory_barrier ();
+       }
 
        sgen_pointer_queue_add (&allocated_blocks, BLOCK_TAG (info));
 
@@ -1623,6 +1628,7 @@ sweep_job_func (void *thread_data_untyped, SgenThreadPoolJob *job)
        }
 
        sgen_pointer_queue_remove_nulls (&allocated_blocks);
+       mono_memory_barrier ();
 
        sweep_finish ();