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));
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);
#endif
} END_FOREACH_THREAD
- release_gc_locks ();
-
count = sgen_thread_handshake (FALSE);
TV_GETTIME (end_sw);
usec = TV_ELAPSED (stop_world_time, end_sw);
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);