X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fsgen%2Fsgen-pinning.c;h=0e711d1aa15a265b4fa466c00a595c884568a9ef;hb=42874b6479cf103ca2e044b95c27a2edbb21d75c;hp=cfe3db1acd0167bd08d1c7e285b6313736460ec3;hpb=1ca65b172d22410fd5f4bf2892a131e787186e2e;p=mono.git diff --git a/mono/sgen/sgen-pinning.c b/mono/sgen/sgen-pinning.c index cfe3db1acd0..0e711d1aa15 100644 --- a/mono/sgen/sgen-pinning.c +++ b/mono/sgen/sgen-pinning.c @@ -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);