MonoThreadInfoWaitRet mono_thread_info_wait_one_handle (MonoThreadHandle *thread_handle, guint32 timeout, gboolean alertable) { MonoOSEventWaitRet res; res = mono_os_event_wait_one (&thread_handle->event, timeout); if (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0) return MONO_THREAD_INFO_WAIT_RET_SUCCESS_0; else if (res == MONO_OS_EVENT_WAIT_RET_ALERTED) return MONO_THREAD_INFO_WAIT_RET_ALERTED; else if (res == MONO_OS_EVENT_WAIT_RET_TIMEOUT) return MONO_THREAD_INFO_WAIT_RET_TIMEOUT; else g_error ("%s: unknown res value %d", __func__, res); }
void mono_runtime_shutdown_stat_profiler (void) { mono_atomic_store_i32 (&sampling_thread_running, 0); mono_profiler_sampling_thread_post (); #ifndef HOST_DARWIN /* * There is a slight problem when we're using CLOCK_PROCESS_CPUTIME_ID: If * we're shutting down and there's largely no activity in the process other * than waiting for the sampler thread to shut down, it can take upwards of * 20 seconds (depending on a lot of factors) for us to shut down because * the sleep progresses very slowly as a result of the low CPU activity. * * We fix this by repeatedly sending the profiler signal to the sampler * thread in order to interrupt the sleep. clock_sleep_ns_abs () will check * sampling_thread_running upon an interrupt and return immediately if it's * zero. profiler_signal_handler () has a special case to ignore the signal * for the sampler thread. */ MonoThreadInfo *info; // Did it shut down already? if ((info = mono_thread_info_lookup (sampling_thread))) { while (!mono_atomic_load_i32 (&sampling_thread_exiting)) { mono_threads_pthread_kill (info, profiler_signal); mono_thread_info_usleep (10 * 1000 /* 10ms */); } // Make sure info can be freed. mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1); } #endif mono_os_event_wait_one (&sampling_thread_exited, MONO_INFINITE_WAIT, FALSE); mono_os_event_destroy (&sampling_thread_exited); /* * We can't safely remove the signal handler because we have no guarantee * that all pending signals have been delivered at this point. This should * not really be a problem anyway. */ //remove_signal_handler (profiler_signal); }