Exemple #1
0
void
mono_w32mutex_abandon (MonoInternalThread *internal_raw)
{
	HANDLE_FUNCTION_ENTER ()

	MONO_HANDLE_DCL (MonoInternalThread, internal);

	g_assert (mono_thread_internal_is_current_handle (internal));

	if (!MONO_HANDLE_GETVAL (internal, owned_mutexes))
		goto exit;

	while (MONO_HANDLE_GETVAL (internal, owned_mutexes)->len) {
		MonoW32Handle *handle_data;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (MONO_HANDLE_GETVAL (internal, owned_mutexes), 0);

		if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
			g_error ("%s: unkown handle %p", __func__, handle);

		if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX)
			g_error ("%s: unkown mutex handle %p", __func__, handle);

		mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (MONO_HANDLE_GETVAL (internal, tid));

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock (handle_data);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		mono_w32handle_unlock (handle_data);
		mono_w32handle_unref (handle_data);
	}

	g_ptr_array_free (MONO_HANDLE_GETVAL (internal, owned_mutexes), TRUE);
	MONO_HANDLE_SETVAL(internal, owned_mutexes, GPtrArray*, NULL);

exit:
	HANDLE_FUNCTION_RETURN ();
}
Exemple #2
0
void
mono_w32mutex_abandon (MonoInternalThread *internal)
{
	g_assert (mono_thread_internal_is_current (internal));

	if (!internal->owned_mutexes)
		return;

	while (internal->owned_mutexes->len) {
		MonoW32Handle *handle_data;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (internal->owned_mutexes, 0);

		if (!mono_w32handle_lookup_and_ref (handle, &handle_data))
			g_error ("%s: unkown handle %p", __func__, handle);

		if (handle_data->type != MONO_W32TYPE_MUTEX && handle_data->type != MONO_W32TYPE_NAMEDMUTEX)
			g_error ("%s: unkown mutex handle %p", __func__, handle);

		mutex_handle = (MonoW32HandleMutex*) handle_data->specific;

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid);

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock (handle_data);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle_data, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_MUTEX, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (handle_data->type), handle);

		mono_w32handle_unlock (handle_data);
		mono_w32handle_unref (handle_data);
	}

	g_ptr_array_free (internal->owned_mutexes, TRUE);
	internal->owned_mutexes = NULL;
}
Exemple #3
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);
}
Exemple #4
0
void
mono_w32mutex_abandon (void)
{
	MonoInternalThread *internal;

	g_assert (mono_thread_internal_current_is_attached ());

	internal = mono_thread_internal_current ();
	g_assert (internal);

	if (!internal->owned_mutexes)
		return;

	while (internal->owned_mutexes->len) {
		MonoW32HandleType type;
		MonoW32HandleMutex *mutex_handle;
		MonoNativeThreadId tid;
		gpointer handle;

		handle = g_ptr_array_index (internal->owned_mutexes, 0);

		switch (type = mono_w32handle_get_type (handle)) {
		case MONO_W32HANDLE_MUTEX:
		case MONO_W32HANDLE_NAMEDMUTEX:
			break;
		default:
			g_assert_not_reached ();
		}

		if (!mono_w32handle_lookup (handle, type, (gpointer *)&mutex_handle)) {
			g_error ("%s: error looking up %s handle %p",
				__func__, mono_w32handle_get_typename (type), handle);
		}

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoning %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);

		tid = MONO_UINT_TO_NATIVE_THREAD_ID (internal->tid);

		if (!pthread_equal (mutex_handle->tid, tid))
			g_error ("%s: trying to release mutex %p acquired by thread %p from thread %p",
				__func__, handle, (gpointer) mutex_handle->tid, (gpointer) tid);

		mono_w32handle_lock_handle (handle);

		mutex_handle->recursion = 0;
		mutex_handle->tid = 0;
		mutex_handle->abandoned = TRUE;

		mono_w32handle_set_signal_state (handle, TRUE, FALSE);

		thread_disown_mutex (internal, handle);

		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: abandoned %s handle %p",
			__func__, mono_w32handle_get_typename (type), handle);

		mono_w32handle_unlock_handle (handle);
	}

	g_ptr_array_free (internal->owned_mutexes, TRUE);
	internal->owned_mutexes = NULL;
}