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 }
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 }
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 }
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); }