Пример #1
0
static int
restart_signal_get (void)
{
#if defined(HOST_ANDROID)
	return SIGXCPU;
#elif defined (SIGRTMIN)
	static int restart_signum = -1;
	if (restart_signum == -1)
		restart_signum = mono_threads_suspend_search_alternative_signal ();
	return restart_signum;
#else
	return SIGXCPU;
#endif
}
Пример #2
0
static int
abort_signal_get (void)
{
#if defined(HOST_ANDROID)
	return SIGTTIN;
#elif defined (SIGRTMIN)
	static int abort_signum = -1;
	if (abort_signum == -1)
		abort_signum = mono_threads_suspend_search_alternative_signal ();
	return abort_signum;
#elif defined (SIGTTIN)
	return SIGTTIN;
#else
	g_error ("unable to get abort signal");
#endif
}
Пример #3
0
static int
suspend_signal_get (void)
{
#if defined(HOST_ANDROID)
	return SIGPWR;
#elif defined (SIGRTMIN)
	static int suspend_signum = -1;
	if (suspend_signum == -1)
		suspend_signum = mono_threads_suspend_search_alternative_signal ();
	return suspend_signum;
#else
#if defined(__APPLE__) || defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
	return SIGXFSZ;
#else
	return SIGPWR;
#endif
#endif
}
Пример #4
0
void
mono_runtime_setup_stat_profiler (void)
{
	/*
	 * Use a real-time signal when possible. This gives us roughly a 99% signal
	 * delivery rate in all cases. On the other hand, using a regular signal
	 * tends to result in awful delivery rates when the application is heavily
	 * loaded.
	 *
	 * We avoid real-time signals on Android as they're super broken in certain
	 * API levels (too small sigset_t, nonsensical SIGRTMIN/SIGRTMAX values,
	 * etc).
	 *
	 * TODO: On Mac, we should explore using the Mach thread suspend/resume
	 * functions and doing the stack walk from the sampling thread. This would
	 * get us a 100% sampling rate. However, this may interfere with the GC's
	 * STW logic. Could perhaps be solved by taking the suspend lock.
	 */
#if defined (USE_POSIX_BACKEND) && defined (SIGRTMIN) && !defined (HOST_ANDROID)
	/* Just take the first real-time signal we can get. */
	profiler_signal = mono_threads_suspend_search_alternative_signal ();
#else
	profiler_signal = SIGPROF;
#endif

	add_signal_handler (profiler_signal, profiler_signal_handler, SA_RESTART);

	mono_counters_register ("Sampling signals sent", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &profiler_signals_sent);
	mono_counters_register ("Sampling signals received", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &profiler_signals_received);
	mono_counters_register ("Sampling signals accepted", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &profiler_signals_accepted);
	mono_counters_register ("Shutdown signals received", MONO_COUNTER_UINT | MONO_COUNTER_PROFILER | MONO_COUNTER_MONOTONIC, &profiler_interrupt_signals_received);

	mono_os_event_init (&sampling_thread_exited, FALSE);

	mono_atomic_store_i32 (&sampling_thread_running, 1);

	MonoError error;
	MonoInternalThread *thread = mono_thread_create_internal (mono_get_root_domain (), sampling_thread_func, NULL, MONO_THREAD_CREATE_FLAGS_NONE, &error);
	mono_error_assert_ok (&error);

	sampling_thread = MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid);
}