[sgen] Add missing memory barrier
authorVlad Brezae <brezaevlad@gmail.com>
Thu, 21 Jul 2016 21:43:40 +0000 (00:43 +0300)
committerVlad Brezae <brezaevlad@gmail.com>
Thu, 21 Jul 2016 22:14:53 +0000 (01:14 +0300)
When doing the first phase of sweeping we tag the block pointer within the block list with a CAS, after which we own the block and we are free to update the state and do sweep computations on the block. When we finish this phase we directly write the untagged block pointer back in the list, making the block available to inspect by other threads. We need a write barrier before writting the untagged pointer back because, when another thread might acquire the block, it might encounter an invalid block state.

mono/sgen/sgen-marksweep.c

index 8b4f3cb612dd4370c6f96a04798abf26ec1cc6cb..6a20d0c57fad1e275e2ffc9e213c3bd385f94155 100644 (file)
@@ -1572,6 +1572,12 @@ ensure_block_is_checked_for_sweeping (guint32 block_index, gboolean wait, gboole
        }
 
  done:
+       /*
+        * Once the block is written back without the checking bit other threads are
+        * free to access it. Make sure the block state is visible before we write it
+        * back.
+        */
+       mono_memory_write_barrier ();
        *block_slot = tagged_block;
        return !!tagged_block;
 }