Пример #1
0
void
mono_threads_core_exit (int exit_code)
{
	MonoThreadInfo *current = mono_thread_info_current ();

#if defined(__native_client__)
	nacl_shutdown_gc_thread();
#endif

	wapi_thread_handle_set_exited (current->handle, exit_code);

	g_assert (mono_threads_get_callbacks ()->thread_exit);
	mono_threads_get_callbacks ()->thread_exit (NULL);
}
Пример #2
0
HANDLE
mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid)
{
	pthread_attr_t attr;
	int res;
	pthread_t thread;
	StartInfo start_info;

	res = pthread_attr_init (&attr);
	g_assert (!res);

	if (stack_size == 0) {
#if HAVE_VALGRIND_MEMCHECK_H
		if (RUNNING_ON_VALGRIND)
			stack_size = 1 << 20;
		else
			stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
#else
		stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
#endif
	}

#ifdef PTHREAD_STACK_MIN
	if (stack_size < PTHREAD_STACK_MIN)
		stack_size = PTHREAD_STACK_MIN;
#endif

#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
	res = pthread_attr_setstacksize (&attr, stack_size);
	g_assert (!res);
#endif

	memset (&start_info, 0, sizeof (StartInfo));
	start_info.start_routine = (gpointer)start_routine;
	start_info.arg = arg;
	start_info.flags = creation_flags;
	MONO_SEM_INIT (&(start_info.registered), 0);

	/* Actually start the thread */
	res = mono_threads_get_callbacks ()->mono_gc_pthread_create (&thread, &attr, inner_start_thread, &start_info);
	if (res) {
		MONO_SEM_DESTROY (&(start_info.registered));
		return NULL;
	}

	/* Wait until the thread register itself in various places */
	while (MONO_SEM_WAIT (&(start_info.registered)) != 0) {
		/*if (EINTR != errno) ABORT("sem_wait failed"); */
	}
	MONO_SEM_DESTROY (&(start_info.registered));

	if (out_tid)
		*out_tid = thread;

	return start_info.handle;
}
Пример #3
0
int
mono_threads_pthread_create (pthread_t *new_thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)
{
	ThreadStartInfo *start_info;
	int result;

	start_info = g_malloc0 (sizeof (ThreadStartInfo));
	if (!start_info)
		return ENOMEM;
	MONO_SEM_INIT (&(start_info->registered), 0);
	start_info->arg = arg;
	start_info->start_routine = start_routine;

	result = mono_threads_get_callbacks ()->mono_gc_pthread_create (new_thread, attr, inner_start_thread, start_info);
	if (result == 0) {
		while (MONO_SEM_WAIT (&(start_info->registered)) != 0) {
			/*if (EINTR != errno) ABORT("sem_wait failed"); */
		}
	}
	MONO_SEM_DESTROY (&(start_info->registered));
	g_free (start_info);
	return result;
}
Пример #4
0
static void*
inner_start_thread (void *arg)
{
	StartInfo *start_info = arg;
	void *t_arg = start_info->arg;
	int res;
	void *(*start_func)(void*) = start_info->start_routine;
	guint32 flags = start_info->flags;
	void *result;
	HANDLE handle;
	MonoThreadInfo *info;

	/* Register the thread with the io-layer */
	handle = wapi_create_thread_handle ();
	if (!handle) {
		res = MONO_SEM_POST (&(start_info->registered));
		g_assert (!res);
		return NULL;
	}
	start_info->handle = handle;

	info = mono_thread_info_attach (&result);
	info->runtime_thread = TRUE;
	info->handle = handle;

	if (flags & CREATE_SUSPENDED) {
		info->create_suspended = TRUE;
		MONO_SEM_INIT (&info->create_suspended_sem, 0);
	}

	/* start_info is not valid after this */
	res = MONO_SEM_POST (&(start_info->registered));
	g_assert (!res);
	start_info = NULL;

	if (flags & CREATE_SUSPENDED) {
		while (MONO_SEM_WAIT (&info->create_suspended_sem) != 0 &&
			   errno == EINTR);
		MONO_SEM_DESTROY (&info->create_suspended_sem);
	}

	/* Run the actual main function of the thread */
	result = start_func (t_arg);

	/*
	mono_thread_info_detach ();
	*/

#if defined(__native_client__)
	nacl_shutdown_gc_thread();
#endif

	wapi_thread_handle_set_exited (handle, GPOINTER_TO_UINT (result));
	/* This is needed by mono_threads_core_unregister () which is called later */
	info->handle = NULL;

	g_assert (mono_threads_get_callbacks ()->thread_exit);
	mono_threads_get_callbacks ()->thread_exit (NULL);
	g_assert_not_reached ();
	return result;
}