[profiler] Avoid a crash at shutdown by installing the assembly unload hook for the...
[mono.git] / mono / utils / mono-threads-coop.c
index a0f161b0f04fd7661d86effb4bc38aad7c74c7bd..03e0aba0bb160e2afbbb4847d79f044076cb9823 100644 (file)
@@ -24,6 +24,7 @@
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-time.h>
 #include <mono/utils/mono-counters.h>
+#include <mono/utils/mono-threads-coop.h>
 
 #ifdef TARGET_OSX
 #include <mono/utils/mach-support.h>
 #define SAVE_REGS_ON_STACK __builtin_unwind_init ();
 #endif
 
-#ifdef USE_COOP_BACKEND
-
 volatile size_t mono_polling_required;
 
-static int coop_reset_blocking_count, coop_try_blocking_count, coop_do_blocking_count, coop_do_polling_count, coop_save_count;
+static int coop_reset_blocking_count;
+static int coop_try_blocking_count;
+static int coop_do_blocking_count;
+static int coop_do_polling_count;
+static int coop_save_count;
 
 void
 mono_threads_state_poll (void)
 {
        MonoThreadInfo *info;
+
+       g_assert (mono_threads_is_coop_enabled ());
+
        ++coop_do_polling_count;
 
        info = mono_thread_info_current_unchecked ();
@@ -93,7 +99,8 @@ copy_stack_data (MonoThreadInfo *info, void* stackdata_begin)
        state = &info->thread_saved_state [SELF_SUSPEND_STATE_INDEX];
 
        stackdata_size = (char*)stackdata_begin - (char*)stackdata_end;
-       g_assert (stackdata_size > 0);
+       if (stackdata_size <= 0)
+               g_error ("stackdata_size = %d, but must be > 0, stackdata_begin = %p, stackdata_end = %p", stackdata_size, stackdata_begin, stackdata_end);
 
        g_byte_array_set_size (info->stackdata, stackdata_size);
        state->gc_stackdata = info->stackdata->data;
@@ -106,6 +113,10 @@ void*
 mono_threads_prepare_blocking (void* stackdata)
 {
        MonoThreadInfo *info;
+
+       if (!mono_threads_is_coop_enabled ())
+               return NULL;
+
        ++coop_do_blocking_count;
 
        info = mono_thread_info_current_unchecked ();
@@ -136,8 +147,12 @@ void
 mono_threads_finish_blocking (void *cookie, void* stackdata)
 {
        static gboolean warned_about_bad_transition;
-       MonoThreadInfo *info = cookie;
+       MonoThreadInfo *info;
+
+       if (!mono_threads_is_coop_enabled ())
+               return;
 
+       info = cookie;
        if (!info)
                return;
 
@@ -167,9 +182,14 @@ mono_threads_finish_blocking (void *cookie, void* stackdata)
 void*
 mono_threads_reset_blocking_start (void* stackdata)
 {
-       MonoThreadInfo *info = mono_thread_info_current_unchecked ();
+       MonoThreadInfo *info;
+
+       if (!mono_threads_is_coop_enabled ())
+               return NULL;
+
        ++coop_reset_blocking_count;
 
+       info = mono_thread_info_current_unchecked ();
        /* If the thread is not attached, it doesn't make sense prepare for suspend. */
        if (!info || !mono_thread_info_is_live (info))
                return NULL;
@@ -197,8 +217,12 @@ mono_threads_reset_blocking_start (void* stackdata)
 void
 mono_threads_reset_blocking_end (void *cookie, void* stackdata)
 {
-       MonoThreadInfo *info = cookie;
+       MonoThreadInfo *info;
+
+       if (!mono_threads_is_coop_enabled ())
+               return;
 
+       info = cookie;
        if (!info)
                return;
 
@@ -210,6 +234,10 @@ void*
 mono_threads_try_prepare_blocking (void* stackdata)
 {
        MonoThreadInfo *info;
+
+       if (!mono_threads_is_coop_enabled ())
+               return NULL;
+
        ++coop_try_blocking_count;
 
        info = mono_thread_info_current_unchecked ();
@@ -239,34 +267,18 @@ retry:
 void
 mono_threads_finish_try_blocking (void* cookie, void* stackdata)
 {
-       mono_threads_finish_blocking (cookie, stackdata);
-}
-
-gboolean
-mono_threads_core_begin_async_resume (MonoThreadInfo *info)
-{
-       g_error ("FIXME");
-       return FALSE;
-}
-
-gboolean
-mono_threads_core_begin_async_suspend (MonoThreadInfo *info, gboolean interrupt_kernel)
-{      
-       mono_threads_add_to_pending_operation_set (info);
-       /* There's nothing else to do after we async request the thread to suspend */
-       return TRUE;
-}
+       if (!mono_threads_is_coop_enabled ())
+               return;
 
-gboolean
-mono_threads_core_check_suspend_result (MonoThreadInfo *info)
-{
-       /* Async suspend can't async fail on coop */
-       return TRUE;
+       mono_threads_finish_blocking (cookie, stackdata);
 }
 
 void
-mono_threads_init_platform (void)
+mono_threads_init_coop (void)
 {
+       if (!mono_threads_is_coop_enabled ())
+               return;
+
        mono_counters_register ("Coop Reset Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_reset_blocking_count);
        mono_counters_register ("Coop Try Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_try_blocking_count);
        mono_counters_register ("Coop Do Blocking", MONO_COUNTER_GC | MONO_COUNTER_INT, &coop_do_blocking_count);
@@ -276,64 +288,33 @@ mono_threads_init_platform (void)
 }
 
 void
-mono_threads_platform_free (MonoThreadInfo *info)
+mono_threads_coop_begin_global_suspend (void)
 {
-#ifdef TARGET_MACH
-       mach_port_deallocate (current_task (), info->native_handle);
-#endif
-
-       //See the above for what's wrong here.
-}
-
-void
-mono_threads_platform_register (MonoThreadInfo *info)
-{
-#ifdef TARGET_MACH
-       char thread_name [64];
-
-       info->native_handle = mach_thread_self ();
-       snprintf (thread_name, 64, "tid_%x", (int)info->native_handle);
-       pthread_setname_np (thread_name);
-#endif
-
-       //See the above for what's wrong here.
-}
-
-void
-mono_threads_core_begin_global_suspend (void)
-{
-       mono_polling_required = 1;
+       if (mono_threads_is_coop_enabled ())
+               mono_polling_required = 1;
 }
 
 void
-mono_threads_core_end_global_suspend (void)
+mono_threads_coop_end_global_suspend (void)
 {
-       mono_polling_required = 0;
+       if (mono_threads_is_coop_enabled ())
+               mono_polling_required = 0;
 }
 
 void*
 mono_threads_enter_gc_unsafe_region (void* stackdata)
 {
+       if (!mono_threads_is_coop_enabled ())
+               return NULL;
+
        return mono_threads_reset_blocking_start (stackdata);
 }
 
 void
 mono_threads_exit_gc_unsafe_region (void *regions_cookie, void* stackdata)
 {
-       mono_threads_reset_blocking_end (regions_cookie, stackdata);
-}
-
-#else
-
-void*
-mono_threads_enter_gc_unsafe_region (void* stackdata)
-{
-       return NULL;
-}
+       if (!mono_threads_is_coop_enabled ())
+               return;
 
-void
-mono_threads_exit_gc_unsafe_region (void *regions_cookie, void* stackdata)
-{
+       mono_threads_reset_blocking_end (regions_cookie, stackdata);
 }
-
-#endif
\ No newline at end of file