Merge pull request #5714 from alexischr/update_bockbuild
[mono.git] / mono / sgen / sgen-pinning.c
index cfe3db1acd0167bd08d1c7e285b6313736460ec3..0e711d1aa15a265b4fa466c00a595c884568a9ef 100644 (file)
@@ -1,5 +1,6 @@
-/*
- * sgen-pinning.c: The pin queue.
+/**
+ * \file
+ * The pin queue.
  *
  * Copyright 2001-2003 Ximian, Inc
  * Copyright 2003-2010 Novell, Inc.
@@ -26,7 +27,7 @@ static size_t last_num_pinned = 0;
  * stay pinned, which means they can't move, therefore they can be scanned.
  */
 static SgenPointerQueue pin_queue_objs;
-static MonoCoopMutex pin_queue_mutex;
+static mono_mutex_t pin_queue_mutex;
 
 #define PIN_HASH_SIZE 1024
 static void *pin_hash_filter [PIN_HASH_SIZE];
@@ -34,15 +35,20 @@ static void *pin_hash_filter [PIN_HASH_SIZE];
 void
 sgen_pinning_init (void)
 {
-       mono_coop_mutex_init (&pin_queue_mutex);
+       mono_os_mutex_init (&pin_queue_mutex);
 }
 
 void
 sgen_init_pinning (void)
 {
-       mono_coop_mutex_lock (&pin_queue_mutex);
        memset (pin_hash_filter, 0, sizeof (pin_hash_filter));
        pin_queue.mem_type = INTERNAL_MEM_PIN_QUEUE;
+}
+
+void
+sgen_init_pinning_for_conc (void)
+{
+       mono_os_mutex_lock (&pin_queue_mutex);
        sgen_pointer_queue_clear (&pin_queue_objs);
 }
 
@@ -51,7 +57,12 @@ sgen_finish_pinning (void)
 {
        last_num_pinned = pin_queue.next_slot;
        sgen_pointer_queue_clear (&pin_queue);
-       mono_coop_mutex_unlock (&pin_queue_mutex);
+}
+
+void
+sgen_finish_pinning_for_conc (void)
+{
+       mono_os_mutex_unlock (&pin_queue_mutex);
 }
 
 void
@@ -66,12 +77,12 @@ sgen_scan_pin_queue_objects (ScanCopyContext ctx)
        int i;
        ScanObjectFunc scan_func = ctx.ops->scan_object;
 
-       mono_coop_mutex_lock (&pin_queue_mutex);
+       mono_os_mutex_lock (&pin_queue_mutex);
        for (i = 0; i < pin_queue_objs.next_slot; ++i) {
                GCObject *obj = (GCObject *)pin_queue_objs.data [i];
                scan_func (obj, sgen_obj_get_descriptor_safe (obj), ctx.queue);
        }
-       mono_coop_mutex_unlock (&pin_queue_mutex);
+       mono_os_mutex_unlock (&pin_queue_mutex);
 }
 
 void
@@ -321,8 +332,11 @@ sgen_cement_lookup_or_register (GCObject *obj)
        SGEN_ASSERT (5, sgen_ptr_in_nursery (obj), "Can only cement pointers to nursery objects");
 
        if (!hash [i].obj) {
-               SGEN_ASSERT (5, !hash [i].count, "Cementing hash inconsistent");
-               hash [i].obj = obj;
+               GCObject *old_obj;
+               old_obj = InterlockedCompareExchangePointer ((gpointer*)&hash [i].obj, obj, NULL);
+               /* Check if the slot was occupied by some other object */
+               if (old_obj != NULL && old_obj != obj)
+                       return FALSE;
        } else if (hash [i].obj != obj) {
                return FALSE;
        }
@@ -330,8 +344,7 @@ sgen_cement_lookup_or_register (GCObject *obj)
        if (hash [i].count >= SGEN_CEMENT_THRESHOLD)
                return TRUE;
 
-       ++hash [i].count;
-       if (hash [i].count == SGEN_CEMENT_THRESHOLD) {
+       if (InterlockedIncrement ((gint32*)&hash [i].count) == SGEN_CEMENT_THRESHOLD) {
                SGEN_ASSERT (9, sgen_get_current_collection_generation () >= 0, "We can only cement objects when we're in a collection pause.");
                SGEN_ASSERT (9, SGEN_OBJECT_IS_PINNED (obj), "Can only cement pinned objects");
                SGEN_CEMENT_OBJECT (obj);