[sgen] Evacuate from emptier blocks to fuller ones
[mono.git] / mono / metadata / threads.c
index 6867741e3ce39026918ea56b45a7c028cbe2e9a8..68c4b9025c0a8812e183ceb1ee2611e8f41c3bb3 100644 (file)
@@ -225,6 +225,9 @@ static gboolean shutting_down = FALSE;
 
 static gint32 managed_thread_id_counter = 0;
 
+/* Class lazy loading functions */
+static GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, System, AppDomainUnloadedException)
+
 static void
 mono_threads_lock (void)
 {
@@ -1580,7 +1583,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
 {
        HANDLE *handles;
        guint32 numhandles;
@@ -1613,15 +1616,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
 
        g_free(handles);
 
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
 /* FIXME: exitContext isnt documented */
@@ -1673,7 +1668,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this_obj, HANDLE handle, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
@@ -1692,18 +1687,10 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
-gboolean
+gint32
 ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
@@ -1722,7 +1709,7 @@ ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, H
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-       return  (!(ret == WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED));
+       return ret;
 }
 
 HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
@@ -2042,6 +2029,7 @@ MonoObject*
 ves_icall_System_Threading_Interlocked_Exchange_T (MonoObject **location, MonoObject *value)
 {
        MonoObject *res;
+       MONO_CHECK_NULL (location, NULL);
        res = (MonoObject *)InterlockedExchangePointer ((volatile gpointer *)location, value);
        mono_gc_wbarrier_generic_nostore (location);
        return res;
@@ -4325,6 +4313,7 @@ static MonoException*
 mono_thread_execute_interruption (void)
 {
        MonoInternalThread *thread = mono_thread_internal_current ();
+       MonoThread *sys_thread = mono_thread_current ();
 
        LOCK_THREAD (thread);
 
@@ -4363,11 +4352,11 @@ mono_thread_execute_interruption (void)
                
                mono_thread_exit ();
                return NULL;
-       } else if (thread->pending_exception) {
+       } else if (sys_thread->pending_exception) {
                MonoException *exc;
 
-               exc = thread->pending_exception;
-               thread->pending_exception = NULL;
+               exc = sys_thread->pending_exception;
+               sys_thread->pending_exception = NULL;
 
         UNLOCK_THREAD (thread);
         return exc;
@@ -4519,6 +4508,7 @@ MonoException*
 mono_thread_get_and_clear_pending_exception (void)
 {
        MonoInternalThread *thread = mono_thread_internal_current ();
+       MonoThread *sys_thread = mono_thread_current ();
 
        /* The thread may already be stopping */
        if (thread == NULL)
@@ -4528,10 +4518,10 @@ mono_thread_get_and_clear_pending_exception (void)
                return mono_thread_execute_interruption ();
        }
        
-       if (thread->pending_exception) {
-               MonoException *exc = thread->pending_exception;
+       if (sys_thread->pending_exception) {
+               MonoException *exc = sys_thread->pending_exception;
 
-               thread->pending_exception = NULL;
+               sys_thread->pending_exception = NULL;
                return exc;
        }
 
@@ -4547,7 +4537,7 @@ mono_thread_get_and_clear_pending_exception (void)
 void
 mono_set_pending_exception (MonoException *exc)
 {
-       MonoInternalThread *thread = mono_thread_internal_current ();
+       MonoThread *thread = mono_thread_current ();
 
        /* The thread may already be stopping */
        if (thread == NULL)
@@ -4682,7 +4672,17 @@ mono_thread_info_get_last_managed (MonoThreadInfo *info)
        MonoJitInfo *ji = NULL;
        if (!info)
                return NULL;
+
+       /*
+        * The suspended thread might be holding runtime locks. Make sure we don't try taking
+        * any runtime locks while unwinding. In coop case we shouldn't safepoint in regions
+        * where we hold runtime locks.
+        */
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_set_is_async_context (TRUE);
        mono_get_eh_callbacks ()->mono_walk_stack_with_state (last_managed, mono_thread_info_get_suspend_state (info), MONO_UNWIND_SIGNAL_SAFE, &ji);
+       if (!mono_threads_is_coop_enabled ())
+               mono_thread_info_set_is_async_context (FALSE);
        return ji;
 }
 
@@ -4959,13 +4959,7 @@ mono_thread_internal_check_for_interruption_critical (MonoInternalThread *thread
 static inline gboolean
 is_appdomainunloaded_exception (MonoClass *klass)
 {
-       static MonoClass *app_domain_unloaded_exception_klass = NULL;
-
-       if (!app_domain_unloaded_exception_klass)
-               app_domain_unloaded_exception_klass = mono_class_from_name (mono_defaults.corlib, "System", "AppDomainUnloadedException");
-       g_assert (app_domain_unloaded_exception_klass);
-
-       return klass == app_domain_unloaded_exception_klass;
+       return klass == mono_class_get_appdomain_unloaded_exception_class ();
 }
 
 static inline gboolean