コード例 #1
0
ファイル: file-mmap-posix.c プロジェクト: mrasanen/mono
static void
file_mmap_init (void)
{
retry:	
	switch (mmap_init_state) {
	case  0:
		if (InterlockedCompareExchange (&mmap_init_state, 1, 0) != 0)
			goto retry;
		named_regions = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, NULL);
		mono_mutex_init (&named_regions_mutex);

		mono_atomic_store_release (&mmap_init_state, 2);
		break;

	case 1:
		do {
			g_usleep (1000); /* Been init'd by other threads, this is very rare. */
		} while (mmap_init_state != 2);
		break;
	case 2:
		break;
	default:
		g_error ("Invalid init state %d", mmap_init_state);
	}
}
コード例 #2
0
ファイル: mono-threads.c プロジェクト: glinos/mono
gboolean
mono_thread_info_resume (MonoNativeThreadId tid)
{
	gboolean result = TRUE;
	MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();	
	MonoThreadInfo *info = mono_thread_info_lookup (tid); /*info on HP1*/
	if (!info)
		return FALSE;

	MONO_SEM_WAIT_UNITERRUPTIBLE (&info->suspend_semaphore);

	THREADS_DEBUG ("resume %x IN COUNT %d\n",tid, info->suspend_count);

	if (info->suspend_count <= 0) {
		MONO_SEM_POST (&info->suspend_semaphore);
		mono_hazard_pointer_clear (hp, 1);
		return FALSE;
	}

	/*
	 * The theory here is that if we manage to suspend the thread it means it did not
	 * start cleanup since it take the same lock. 
	*/
	g_assert (mono_thread_info_get_tid (info));

	if (--info->suspend_count == 0)
		result = mono_thread_info_resume_internal (info);

	MONO_SEM_POST (&info->suspend_semaphore);
	mono_hazard_pointer_clear (hp, 1);
	mono_atomic_store_release (&mono_thread_info_current ()->inside_critical_region, FALSE);

	return result;
}
コード例 #3
0
ファイル: mono-threads.c プロジェクト: Adamcbrz/mono
void
mono_thread_info_finish_suspend_and_resume (MonoThreadInfo *info)
{
	MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();

	/*Resume can access info after the target has resumed, so we must ensure it won't touch freed memory. */
	mono_hazard_pointer_set (hp, 1, info);
	mono_thread_info_core_resume (info);
	mono_hazard_pointer_clear (hp, 1);

	mono_atomic_store_release (&mono_thread_info_current ()->inside_critical_region, FALSE);
}
コード例 #4
0
ファイル: mono-threads.c プロジェクト: Adamcbrz/mono
/*
WARNING:
If we are trying to suspend a target that is on a critical region
and running a syscall we risk looping forever if @interrupt_kernel is FALSE.
So, be VERY carefull in calling this with @interrupt_kernel == FALSE.

Info is not put on a hazard pointer as a suspended thread cannot exit and be freed.

This function MUST be matched with mono_thread_info_finish_suspend or mono_thread_info_finish_suspend_and_resume
*/
MonoThreadInfo*
mono_thread_info_safe_suspend_sync (MonoNativeThreadId id, gboolean interrupt_kernel)
{
	MonoThreadInfo *info = NULL;
	int sleep_duration = 0;

	/*FIXME: unify this with self-suspend*/
	g_assert (id != mono_native_thread_id_get ());

	mono_thread_info_suspend_lock ();

	for (;;) {
		const char *suspend_error = "Unknown error";
		if (!(info = mono_thread_info_suspend_sync (id, interrupt_kernel, &suspend_error))) {
			g_warning ("failed to suspend thread %p due to %s, hopefully it is dead", (gpointer)id, suspend_error);
			mono_thread_info_suspend_unlock ();
			return NULL;
		}
		/*WARNING: We now are in interrupt context until we resume the thread. */
		if (!is_thread_in_critical_region (info))
			break;

		if (!mono_thread_info_core_resume (info)) {
			g_warning ("failed to resume thread %p, hopefully it is dead", (gpointer)id);
			mono_hazard_pointer_clear (mono_hazard_pointer_get (), 1);
			mono_thread_info_suspend_unlock ();
			return NULL;
		}
		THREADS_DEBUG ("restarted thread %p\n", (gpointer)id);

		if (!sleep_duration) {
#ifdef HOST_WIN32
			SwitchToThread ();
#else
			sched_yield ();
#endif
		}
		else {
			g_usleep (sleep_duration);
		}
		sleep_duration += 10;
	}

	/* XXX this clears HP 1, so we restated it again */
	mono_atomic_store_release (&mono_thread_info_current ()->inside_critical_region, TRUE);
	mono_thread_info_suspend_unlock ();

	return info;
}
コード例 #5
0
ファイル: mono-threads.c プロジェクト: glinos/mono
void
mono_thread_info_finish_suspend (void)
{
	mono_atomic_store_release (&mono_thread_info_current ()->inside_critical_region, FALSE);
}