[threads] Enable blocking transition with MONO_ENABLE_BLOCKING_TRANSITION env variabl...
[mono.git] / mono / metadata / threads.c
index 69a00d0b6880b51fd2f4a92f6c52973468f77486..e19f7e0735193cadde3d8bff77de62b48516ad75 100644 (file)
@@ -5107,35 +5107,32 @@ ves_icall_System_Threading_Thread_GetStackTraces (MonoArray **out_threads, MonoA
 /*
  * mono_threads_attach_coop: called by native->managed wrappers
  *
- * In non-coop mode:
- *  - @dummy: is NULL
+ *  - @dummy:
+ *    - blocking mode: contains gc unsafe transition cookie
+ *    - non-blocking mode: contains random data
  *  - @return: the original domain which needs to be restored, or NULL.
- *
- * In coop mode:
- *  - @dummy: contains the original domain
- *  - @return: a cookie containing current MonoThreadInfo*.
  */
 gpointer
 mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy)
 {
        MonoDomain *orig;
-       gboolean fresh_thread = FALSE;
+       MonoThreadInfo *info;
+       gboolean external;
+
+       orig = mono_domain_get ();
 
        if (!domain) {
                /* Happens when called from AOTed code which is only used in the root domain. */
                domain = mono_get_root_domain ();
+               g_assert (domain);
        }
 
-       g_assert (domain);
-
        /* On coop, when we detached, we moved the thread from  RUNNING->BLOCKING.
         * If we try to reattach we do a BLOCKING->RUNNING transition.  If the thread
         * is fresh, mono_thread_attach() will do a STARTING->RUNNING transition so
         * we're only responsible for making the cookie. */
-       if (mono_threads_is_coop_enabled ()) {
-               MonoThreadInfo *info = mono_thread_info_current_unchecked ();
-               fresh_thread = !info || !mono_thread_info_is_live (info);
-       }
+       if (mono_threads_is_blocking_transition_enabled ())
+               external = !(info = mono_thread_info_current_unchecked ()) || !mono_thread_info_is_live (info);
 
        if (!mono_thread_internal_current ()) {
                mono_thread_attach_full (domain, FALSE);
@@ -5144,61 +5141,52 @@ mono_threads_attach_coop (MonoDomain *domain, gpointer *dummy)
                mono_thread_set_state (mono_thread_internal_current (), ThreadState_Background);
        }
 
-       orig = mono_domain_get ();
        if (orig != domain)
                mono_domain_set (domain, TRUE);
 
-       if (!mono_threads_is_coop_enabled ())
-               return orig != domain ? orig : NULL;
-
-       if (fresh_thread) {
-               *dummy = NULL;
-               /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
-                * return the right cookie. */
-               return mono_threads_enter_gc_unsafe_region_cookie ();
-       } else {
-               *dummy = orig;
-               /* thread state (BLOCKING|RUNNING) -> RUNNING */
-               return mono_threads_enter_gc_unsafe_region (dummy);
+       if (mono_threads_is_blocking_transition_enabled ()) {
+               if (external) {
+                       /* mono_thread_attach put the thread in RUNNING mode from STARTING, but we need to
+                        * return the right cookie. */
+                       *dummy = mono_threads_enter_gc_unsafe_region_cookie ();
+               } else {
+                       /* thread state (BLOCKING|RUNNING) -> RUNNING */
+                       *dummy = mono_threads_enter_gc_unsafe_region (dummy);
+               }
        }
+
+       return orig;
 }
 
 /*
  * mono_threads_detach_coop: called by native->managed wrappers
  *
- * In non-coop mode:
  *  - @cookie: the original domain which needs to be restored, or NULL.
- *  - @dummy: is NULL
- *
- * In coop mode:
- *  - @cookie: contains current MonoThreadInfo* if it was in BLOCKING mode, NULL otherwise
- *  - @dummy: contains the original domain
+ *  - @dummy:
+ *    - blocking mode: contains gc unsafe transition cookie
+ *    - non-blocking mode: contains random data
  */
 void
 mono_threads_detach_coop (gpointer cookie, gpointer *dummy)
 {
        MonoDomain *domain, *orig;
 
-       if (!mono_threads_is_coop_enabled ()) {
-               orig = (MonoDomain*) cookie;
-               if (orig)
-                       mono_domain_set (orig, TRUE);
-       } else {
-               orig = (MonoDomain*) *dummy;
+       orig = (MonoDomain*) cookie;
 
-               domain = mono_domain_get ();
-               g_assert (domain);
+       domain = mono_domain_get ();
+       g_assert (domain);
 
+       if (mono_threads_is_blocking_transition_enabled ()) {
                /* it won't do anything if cookie is NULL
                 * thread state RUNNING -> (RUNNING|BLOCKING) */
-               mono_threads_exit_gc_unsafe_region (cookie, dummy);
+               mono_threads_exit_gc_unsafe_region (*dummy, dummy);
+       }
 
-               if (orig != domain) {
-                       if (!orig)
-                               mono_domain_unset ();
-                       else
-                               mono_domain_set (orig, TRUE);
-               }
+       if (orig != domain) {
+               if (!orig)
+                       mono_domain_unset ();
+               else
+                       mono_domain_set (orig, TRUE);
        }
 }