X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fmetadata%2Fmonitor.c;h=b05a8416aac761b86579a210988f5627e168bc6d;hb=c5512c0d3e2b102ed16158ce8c599c8203ccd510;hp=0d9001be1a05514840d263c456affd595d3765e7;hpb=8ae7b6d6b950e5ee5fcd4a6625e0f467340dddee;p=mono.git diff --git a/mono/metadata/monitor.c b/mono/metadata/monitor.c index 0d9001be1a0..b05a8416aac 100644 --- a/mono/metadata/monitor.c +++ b/mono/metadata/monitor.c @@ -20,7 +20,7 @@ #include #include #include -#include +#include #include #include #include @@ -76,8 +76,8 @@ struct _MonitorArray { MonoThreadsSync monitors [MONO_ZERO_LEN_ARRAY]; }; -#define mono_monitor_allocator_lock() mono_mutex_lock (&monitor_mutex) -#define mono_monitor_allocator_unlock() mono_mutex_unlock (&monitor_mutex) +#define mono_monitor_allocator_lock() mono_os_mutex_lock (&monitor_mutex) +#define mono_monitor_allocator_unlock() mono_os_mutex_unlock (&monitor_mutex) static mono_mutex_t monitor_mutex; static MonoThreadsSync *monitor_freelist; static MonitorArray *monitor_allocated; @@ -248,7 +248,7 @@ lock_word_new_flat (gint32 owner) void mono_monitor_init (void) { - mono_mutex_init_recursive (&monitor_mutex); + mono_os_mutex_init_recursive (&monitor_mutex); } void @@ -257,11 +257,11 @@ mono_monitor_cleanup (void) MonoThreadsSync *mon; /* MonitorArray *marray, *next = NULL; */ - /*mono_mutex_destroy (&monitor_mutex);*/ + /*mono_os_mutex_destroy (&monitor_mutex);*/ /* The monitors on the freelist don't have weak links - mark them */ - for (mon = monitor_freelist; mon; mon = mon->data) - mon->wait_list = (gpointer)-1; + for (mon = monitor_freelist; mon; mon = (MonoThreadsSync *)mon->data) + mon->wait_list = (GSList *)-1; /* * FIXME: This still crashes with sgen (async_read.exe) @@ -319,7 +319,7 @@ mono_locks_dump (gboolean include_untaken) int used = 0, on_freelist = 0, to_recycle = 0, total = 0, num_arrays = 0; MonoThreadsSync *mon; MonitorArray *marray; - for (mon = monitor_freelist; mon; mon = mon->data) + for (mon = monitor_freelist; mon; mon = (MonoThreadsSync *)mon->data) on_freelist++; for (marray = monitor_allocated; marray; marray = marray->next) { total += marray->num_monitors; @@ -330,8 +330,8 @@ mono_locks_dump (gboolean include_untaken) if (i < marray->num_monitors - 1) to_recycle++; } else { - if (!monitor_is_on_freelist (mon->data)) { - MonoObject *holder = mono_gc_weak_link_get (&mon->data); + if (!monitor_is_on_freelist ((MonoThreadsSync *)mon->data)) { + MonoObject *holder = (MonoObject *)mono_gchandle_get_target ((guint32)mon->data); if (mon_status_get_owner (mon->status)) { g_print ("Lock %p in object %p held by thread %d, nest level: %d\n", mon, holder, mon_status_get_owner (mon->status), mon->nest); @@ -378,39 +378,39 @@ mon_finalize (MonoThreadsSync *mon) static MonoThreadsSync * mon_new (gsize id) { - MonoThreadsSync *new; + MonoThreadsSync *new_; if (!monitor_freelist) { MonitorArray *marray; int i; /* see if any sync block has been collected */ - new = NULL; + new_ = NULL; for (marray = monitor_allocated; marray; marray = marray->next) { for (i = 0; i < marray->num_monitors; ++i) { - if (marray->monitors [i].data == NULL) { - new = &marray->monitors [i]; - if (new->wait_list) { + if (mono_gchandle_get_target ((guint32)marray->monitors [i].data) == NULL) { + new_ = &marray->monitors [i]; + if (new_->wait_list) { /* Orphaned events left by aborted threads */ - while (new->wait_list) { + while (new_->wait_list) { LOCK_DEBUG (g_message (G_GNUC_PRETTY_FUNCTION ": (%d): Closing orphaned event %d", mono_thread_info_get_small_id (), new->wait_list->data)); - CloseHandle (new->wait_list->data); - new->wait_list = g_slist_remove (new->wait_list, new->wait_list->data); + CloseHandle (new_->wait_list->data); + new_->wait_list = g_slist_remove (new_->wait_list, new_->wait_list->data); } } - mono_gc_weak_link_remove (&new->data, TRUE); - new->data = monitor_freelist; - monitor_freelist = new; + mono_gchandle_free ((guint32)new_->data); + new_->data = monitor_freelist; + monitor_freelist = new_; } } /* small perf tweak to avoid scanning all the blocks */ - if (new) + if (new_) break; } /* need to allocate a new array of monitors */ if (!monitor_freelist) { MonitorArray *last; LOCK_DEBUG (g_message ("%s: allocating more monitors: %d", __func__, array_size)); - marray = g_malloc0 (sizeof (MonoArray) + array_size * sizeof (MonoThreadsSync)); + marray = (MonitorArray *)g_malloc0 (MONO_SIZEOF_MONO_ARRAY + array_size * sizeof (MonoThreadsSync)); marray->num_monitors = array_size; array_size *= 2; /* link into the freelist */ @@ -433,18 +433,18 @@ mon_new (gsize id) } } - new = monitor_freelist; - monitor_freelist = new->data; + new_ = monitor_freelist; + monitor_freelist = (MonoThreadsSync *)new_->data; - new->status = mon_status_set_owner (0, id); - new->status = mon_status_init_entry_count (new->status); - new->nest = 1; - new->data = NULL; + new_->status = mon_status_set_owner (0, id); + new_->status = mon_status_init_entry_count (new_->status); + new_->nest = 1; + new_->data = NULL; #ifndef DISABLE_PERFCOUNTERS mono_perfcounters->gc_sync_blocks++; #endif - return new; + return new_; } static MonoThreadsSync* @@ -454,7 +454,7 @@ alloc_mon (MonoObject *obj, gint32 id) mono_monitor_allocator_lock (); mon = mon_new (id); - mono_gc_weak_link_add (&mon->data, obj, TRUE); + mon->data = (void *)(size_t)mono_gchandle_new_weakref (obj, TRUE); mono_monitor_allocator_unlock (); return mon; @@ -465,7 +465,7 @@ static void discard_mon (MonoThreadsSync *mon) { mono_monitor_allocator_lock (); - mono_gc_weak_link_remove (&mon->data, TRUE); + mono_gchandle_free ((guint32)mon->data); mon_finalize (mon); mono_monitor_allocator_unlock (); } @@ -493,7 +493,7 @@ mono_monitor_inflate_owned (MonoObject *obj, int id) nlw = lock_word_new_inflated (mon); mono_memory_write_barrier (); - tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync); + tmp_lw.sync = (MonoThreadsSync *)InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync); if (tmp_lw.sync != old_lw.sync) { /* Someone else inflated the lock in the meantime */ discard_mon (mon); @@ -536,7 +536,7 @@ mono_monitor_inflate (MonoObject *obj) mon->nest = lock_word_get_nest (old_lw); } mono_memory_write_barrier (); - tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync); + tmp_lw.sync = (MonoThreadsSync *)InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, old_lw.sync); if (tmp_lw.sync == old_lw.sync) { /* Successfully inflated the lock */ return; @@ -592,7 +592,7 @@ mono_object_hash (MonoObject* obj) LockWord old_lw; lw = lock_word_new_thin_hash (hash); - old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL); + old_lw.sync = (MonoThreadsSync *)InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, lw.sync, NULL); if (old_lw.sync == NULL) { return hash; } @@ -707,7 +707,7 @@ mono_monitor_exit_flat (MonoObject *obj, LockWord old_lw) else new_lw.lock_word = 0; - tmp_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, new_lw.sync, old_lw.sync); + tmp_lw.sync = (MonoThreadsSync *)InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, new_lw.sync, old_lw.sync); if (old_lw.sync != tmp_lw.sync) { /* Someone inflated the lock in the meantime */ mono_monitor_exit_inflated (obj); @@ -896,7 +896,7 @@ retry_contended: * We have to obey a stop/suspend request even if * allow_interruption is FALSE to avoid hangs at shutdown. */ - if (!mono_thread_test_state (mono_thread_internal_current (), (ThreadState_StopRequested|ThreadState_SuspendRequested))) { + if (!mono_thread_test_state (mono_thread_internal_current (), (MonoThreadState)(ThreadState_StopRequested | ThreadState_SuspendRequested))) { if (ms != INFINITE) { now = mono_msec_ticks (); if (now < then) { @@ -981,7 +981,7 @@ mono_monitor_try_enter_internal (MonoObject *obj, guint32 ms, gboolean allow_int } else { LockWord nlw, old_lw; nlw = lock_word_increment_nest (lw); - old_lw.sync = InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, lw.sync); + old_lw.sync = (MonoThreadsSync *)InterlockedCompareExchangePointer ((gpointer*)&obj->synchronisation, nlw.sync, lw.sync); if (old_lw.sync != lw.sync) { /* Someone else inflated it in the meantime */ g_assert (lock_word_is_inflated (old_lw)); @@ -1009,6 +1009,12 @@ mono_monitor_enter (MonoObject *obj) } gboolean +mono_monitor_enter_fast (MonoObject *obj) +{ + return mono_monitor_try_enter_internal (obj, 0, FALSE) == 1; +} + +gboolean mono_monitor_try_enter (MonoObject *obj, guint32 ms) { return mono_monitor_try_enter_internal (obj, ms, FALSE) == 1; @@ -1036,8 +1042,8 @@ mono_monitor_exit (MonoObject *obj) mono_monitor_exit_flat (obj, lw); } -void** -mono_monitor_get_object_monitor_weak_link (MonoObject *object) +guint32 +mono_monitor_get_object_monitor_gchandle (MonoObject *object) { LockWord lw; @@ -1045,10 +1051,9 @@ mono_monitor_get_object_monitor_weak_link (MonoObject *object) if (lock_word_is_inflated (lw)) { MonoThreadsSync *mon = lock_word_get_inflated_lock (lw); - if (mon->data) - return &mon->data; + return (guint32)mon->data; } - return NULL; + return 0; } /* @@ -1101,7 +1106,6 @@ ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (MonoObject void mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken) { - if (*lock_taken == 1) { mono_set_pending_exception (mono_get_exception_argument ("lockTaken", "lockTaken is already true")); return; @@ -1110,6 +1114,23 @@ mono_monitor_enter_v4 (MonoObject *obj, char *lock_taken) ves_icall_System_Threading_Monitor_Monitor_try_enter_with_atomic_var (obj, INFINITE, lock_taken); } +/* + * mono_monitor_enter_v4_fast: + * + * Same as mono_monitor_enter_v4, but return immediately if the + * monitor cannot be acquired. + * Returns TRUE if the lock was acquired, FALSE otherwise. + */ +gboolean +mono_monitor_enter_v4_fast (MonoObject *obj, char *lock_taken) +{ + if (*lock_taken == 1) + return FALSE; + gint32 res = mono_monitor_try_enter_internal (obj, 0, TRUE); + *lock_taken = res == 1; + return res == 1; +} + gboolean ves_icall_System_Threading_Monitor_Monitor_test_owner (MonoObject *obj) {