[threading] When checking if a thread is in a critical region, ask the GC too.
authorRodrigo Kumpera <kumpera@gmail.com>
Mon, 2 Feb 2015 16:04:37 +0000 (11:04 -0500)
committerRodrigo Kumpera <kumpera@gmail.com>
Mon, 23 Feb 2015 20:54:04 +0000 (15:54 -0500)
MonoThreads was previously ignoring sgen's in_critical_region, which could lead
to a thread suspended inside a gc critical region leading to the GC not been able
to STW.

mono/metadata/sgen-gc.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h

index 0bb81107f6e183fa0aec37e3e89c80c496238e7d..b149edf774f21a3d3675cf39b2d4da7fcd97b186 100644 (file)
@@ -4633,6 +4633,12 @@ parse_double_in_interval (const char *env_var, const char *opt_name, const char
        return TRUE;
 }
 
+gboolean
+thread_in_critical_region (SgenThreadInfo *info)
+{
+       return info->in_critical_region;
+}
+
 void
 mono_gc_base_init (void)
 {
@@ -4682,6 +4688,7 @@ mono_gc_base_init (void)
        cb.thread_unregister = sgen_thread_unregister;
        cb.thread_attach = sgen_thread_attach;
        cb.mono_method_is_critical = (gpointer)is_critical_method;
+       cb.mono_thread_in_critical_region = thread_in_critical_region;
 #ifndef HOST_WIN32
        cb.thread_exit = mono_gc_pthread_exit;
        cb.mono_gc_pthread_create = (gpointer)mono_gc_pthread_create;
index 02510ab5a5194cf60546bba0da53980e0d3788dd..144c4ac708b1fc6e52d834a4f67033833ce886a4 100644 (file)
@@ -610,9 +610,15 @@ is_thread_in_critical_region (MonoThreadInfo *info)
        MonoMethod *method;
        MonoJitInfo *ji;
 
+       /* Are we inside a system critical region? */
        if (info->inside_critical_region)
                return TRUE;
 
+       /* Are we inside a GC critical region? */
+       if (threads_callbacks.mono_thread_in_critical_region && threads_callbacks.mono_thread_in_critical_region (info)) {
+               return TRUE;
+       }
+
        /* The target thread might be shutting down and the domain might be null, which means no managed code left to run. */
        if (!info->suspend_state.unwind_data [MONO_UNWIND_DATA_DOMAIN])
                return FALSE;
index 0565b71abb2de0fe6d87c30fa4deb48445fb13b2..a63970d4f7daba740100b134fdfa74bd07ff752e 100644 (file)
@@ -188,6 +188,7 @@ typedef struct {
        void (*thread_detach)(THREAD_INFO_TYPE *info);
        void (*thread_attach)(THREAD_INFO_TYPE *info);
        gboolean (*mono_method_is_critical) (void *method);
+       gboolean (*mono_thread_in_critical_region) (THREAD_INFO_TYPE *info);
        void (*thread_exit)(void *retval);
 #ifndef HOST_WIN32
        int (*mono_gc_pthread_create) (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg);