[runtime] Filter out events with same name
[mono.git] / mono / metadata / sgen-stw.c
index 669d34fc4ea7e6b20fa4d7f7007145be438f42b7..12111cbc32dd66949192143a28b0c9935f37abbb 100755 (executable)
@@ -119,10 +119,6 @@ restart_threads_until_none_in_managed_allocator (void)
                        gboolean result;
                        if (info->skip || info->gc_disabled)
                                continue;
-#ifdef SGEN_POSIX_STW
-                       if (info->signal < 0)
-                               continue;
-#endif
                        if (mono_thread_info_run_state (info) == STATE_RUNNING && (!info->stack_start || info->in_critical_region || info->info.inside_critical_region ||
                                        is_ip_in_managed_allocator (info->stopped_domain, info->stopped_ip))) {
                                binary_protocol_thread_restart ((gpointer)mono_thread_info_get_tid (info));
@@ -151,11 +147,7 @@ restart_threads_until_none_in_managed_allocator (void)
                sgen_wait_for_suspend_ack (restart_count);
 
                if (sleep_duration < 0) {
-#ifdef HOST_WIN32
-                       SwitchToThread ();
-#else
-                       sched_yield ();
-#endif
+                       mono_thread_info_yield ();
                        sleep_duration = 0;
                } else {
                        g_usleep (sleep_duration);
@@ -261,8 +253,6 @@ sgen_restart_world (int generation, GGTimingInfo *timing)
 #endif
        } END_FOREACH_THREAD
 
-       release_gc_locks ();
-
        count = sgen_thread_handshake (FALSE);
        TV_GETTIME (end_sw);
        usec = TV_ELAPSED (stop_world_time, end_sw);
@@ -271,7 +261,19 @@ sgen_restart_world (int generation, GGTimingInfo *timing)
        mono_profiler_gc_event (MONO_GC_EVENT_POST_START_WORLD, generation);
        MONO_GC_WORLD_RESTART_END (generation);
 
-       mono_thread_hazardous_try_free_some ();
+       /*
+        * We must release the thread info suspend lock after doing
+        * the thread handshake.  Otherwise, if the GC stops the world
+        * and a thread is in the process of starting up, but has not
+        * yet registered (it's not in the thread_list), it is
+        * possible that the thread does register while the world is
+        * stopped.  When restarting the GC will then try to restart
+        * said thread, but since it never got the suspend signal, it
+        * cannot answer the restart signal, so a deadlock results.
+        */
+       release_gc_locks ();
+
+       sgen_try_free_some_memory = TRUE;
 
        sgen_bridge_processing_finish (generation);