Преглед изворни кода

[threads] Remove mono_threads_create_thread (#4411)

Ludovic Henry пре 8 година
родитељ
комит
30d60224a8

+ 1 - 1
mcs/class/corlib/System.Threading/Thread.cs

@@ -60,7 +60,7 @@ namespace System.Threading {
 		private int abort_state_handle;
 		/* thread_id is only accessed from unmanaged code */
 		internal Int64 thread_id;
-		private IntPtr stack_ptr;
+		private IntPtr debugger_thread; // FIXME switch to bool as soon as CI testing with corlib version bump works
 		private UIntPtr static_data; /* GC-tracked */
 		private IntPtr runtime_thread_info;
 		/* current System.Runtime.Remoting.Contexts.Context instance

+ 12 - 11
mono/metadata/appdomain.c

@@ -2479,14 +2479,12 @@ unload_thread_main (void *arg)
 	MonoError error;
 	unload_data *data = (unload_data*)arg;
 	MonoDomain *domain = data->domain;
-	MonoThread *thread;
+	MonoInternalThread *internal;
 	int i;
 
-	/* Have to attach to the runtime so shutdown can wait for this thread */
-	/* Force it to be attached to avoid racing during shutdown. */
-	thread = mono_thread_attach_full (mono_get_root_domain (), TRUE);
+	internal = mono_thread_internal_current ();
 
-	mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE, FALSE, &error);
+	mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "Domain unloader"), TRUE, FALSE, &error);
 	if (!is_ok (&error)) {
 		data->failure_reason = g_strdup (mono_error_get_message (&error));
 		mono_error_cleanup (&error);
@@ -2556,13 +2554,11 @@ unload_thread_main (void *arg)
 
 	mono_atomic_store_release (&data->done, TRUE);
 	unload_data_unref (data);
-	mono_thread_detach (thread);
 	return 0;
 
 failure:
 	mono_atomic_store_release (&data->done, TRUE);
 	unload_data_unref (data);
-	mono_thread_detach (thread);
 	return 1;
 }
 
@@ -2619,7 +2615,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
 	MonoAppDomainState prev_state;
 	MonoMethod *method;
 	unload_data *thread_data;
-	MonoNativeThreadId tid;
+	MonoInternalThread *internal;
 	MonoDomain *caller_domain = mono_domain_get ();
 
 	/* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, mono_native_thread_id_get ()); */
@@ -2676,10 +2672,15 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
 	/* 
 	 * First we create a separate thread for unloading, since
 	 * we might have to abort some threads, including the current one.
+	 *
+	 * Have to attach to the runtime so shutdown can wait for this thread.
+	 *
+	 * Force it to be attached to avoid racing during shutdown.
 	 */
-	thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, NULL, &tid);
-	if (thread_handle == NULL)
-		return;
+	internal = mono_thread_create_internal (mono_get_root_domain (), unload_thread_main, thread_data, MONO_THREAD_CREATE_FLAGS_FORCE_CREATE, &error);
+	mono_error_assert_ok (&error);
+
+	thread_handle = mono_threads_open_thread_handle (internal->handle);
 
 	/* Wait for the thread */	
 	while (!thread_data->done && guarded_wait (thread_handle, MONO_INFINITE_WAIT, TRUE) == MONO_THREAD_INFO_WAIT_RET_ALERTED) {

+ 15 - 10
mono/metadata/attach.c

@@ -475,12 +475,18 @@ transport_send (int fd, guint8 *data, int len)
 static void
 transport_start_receive (void)
 {
+	MonoError error;
+	MonoInternalThread *internal;
+
 	transport_connect ();
 
 	if (!listen_fd)
 		return;
 
-	receiver_thread_handle = mono_threads_create_thread (receiver_thread, NULL, NULL, NULL);
+	internal = mono_thread_create_internal (mono_get_root_domain (), receiver_thread, NULL, MONO_THREAD_CREATE_FLAGS_NONE, &error);
+	mono_error_assert_ok (&error);
+
+	receiver_thread_handle = mono_threads_open_thread_handle (internal->handle);
 	g_assert (receiver_thread_handle);
 }
 
@@ -492,8 +498,15 @@ receiver_thread (void *arg)
 	guint8 buffer [256];
 	guint8 *p, *p_end;
 	MonoObject *exc;
+	MonoInternalThread *internal;
 
-	mono_native_thread_set_name (mono_native_thread_id_get (), "Attach receiver");
+	internal = mono_thread_internal_current ();
+	mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "Attach receiver"), TRUE, FALSE, &error);
+	mono_error_assert_ok (&error);
+	/* Ask the runtime to not abort this thread */
+	//internal->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
+	/* Ask the runtime to not wait for this thread */
+	internal->state |= ThreadState_Background;
 
 	printf ("attach: Listening on '%s'...\n", server_uri);
 
@@ -505,14 +518,6 @@ receiver_thread (void *arg)
 
 		printf ("attach: Connected.\n");
 
-		MonoThread *thread = mono_thread_attach (mono_get_root_domain ());
-		mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Attach receiver"), TRUE, FALSE, &error);
-		mono_error_assert_ok (&error);
-		/* Ask the runtime to not abort this thread */
-		//mono_thread_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
-		/* Ask the runtime to not wait for this thread */
-		thread->internal_thread->state |= ThreadState_Background;
-
 		while (TRUE) {
 			char *cmd, *agent_name, *agent_args;
 			guint8 *body;

+ 1 - 1
mono/metadata/gc.c

@@ -921,7 +921,7 @@ void
 mono_gc_init_finalizer_thread (void)
 {
 	MonoError error;
-	gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, FALSE, 0, &error);
+	gc_thread = mono_thread_create_internal (mono_domain_get (), finalizer_thread, NULL, MONO_THREAD_CREATE_FLAGS_NONE, &error);
 	mono_error_assert_ok (&error);
 }
 

+ 1 - 1
mono/metadata/object-internals.h

@@ -369,7 +369,7 @@ struct _MonoInternalThread {
 	MonoException *abort_exc;
 	int abort_state_handle;
 	guint64 tid;	/* This is accessed as a gsize in the code (so it can hold a 64bit pointer on systems that need it), but needs to reserve 64 bits of space on all machines as it corresponds to a field in managed code */
-	gpointer stack_ptr;
+	gsize debugger_thread; // FIXME switch to bool as soon as CI testing with corlib version bump works
 	gpointer *static_data;
 	void *thread_info; /*This is MonoThreadInfo*, but to simplify dependencies, let's make it a void* here. */
 	MonoAppContext *current_appcontext;

+ 1 - 1
mono/metadata/threadpool-io.c

@@ -556,7 +556,7 @@ initialize (void)
 		g_error ("initialize: backend->init () failed");
 
 	MonoError error;
-	if (!mono_thread_create_internal (mono_get_root_domain (), selector_thread, NULL, TRUE, SMALL_STACK, &error))
+	if (!mono_thread_create_internal (mono_get_root_domain (), selector_thread, NULL, MONO_THREAD_CREATE_FLAGS_THREADPOOL | MONO_THREAD_CREATE_FLAGS_SMALL_STACK, &error))
 		g_error ("initialize: mono_thread_create_internal () failed due to %s", mono_error_get_message (&error));
 }
 

+ 2 - 2
mono/metadata/threadpool-worker-default.c

@@ -599,7 +599,7 @@ worker_try_create (void)
 		counter._.starting ++;
 	});
 
-	thread = mono_thread_create_internal (mono_get_root_domain (), worker_thread, NULL, TRUE, 0, &error);
+	thread = mono_thread_create_internal (mono_get_root_domain (), worker_thread, NULL, MONO_THREAD_CREATE_FLAGS_THREADPOOL, &error);
 	if (!thread) {
 		mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_THREADPOOL, "[%p] try create worker, failed: could not create thread due to %s", mono_native_thread_id_get (), mono_error_get_message (&error));
 		mono_error_cleanup (&error);
@@ -819,7 +819,7 @@ monitor_ensure_running (void)
 				return;
 			if (InterlockedCompareExchange (&worker.monitor_status, MONITOR_STATUS_REQUESTED, MONITOR_STATUS_NOT_RUNNING) == MONITOR_STATUS_NOT_RUNNING) {
 				// printf ("monitor_thread: creating\n");
-				if (!mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, TRUE, SMALL_STACK, &error)) {
+				if (!mono_thread_create_internal (mono_get_root_domain (), monitor_thread, NULL, MONO_THREAD_CREATE_FLAGS_THREADPOOL | MONO_THREAD_CREATE_FLAGS_SMALL_STACK, &error)) {
 					// printf ("monitor_thread: creating failed\n");
 					worker.monitor_status = MONITOR_STATUS_NOT_RUNNING;
 					mono_error_cleanup (&error);

+ 0 - 2
mono/metadata/threadpool.h

@@ -7,8 +7,6 @@
 #include <mono/metadata/exception.h>
 #include <mono/metadata/object-internals.h>
 
-#define SMALL_STACK (sizeof (gpointer) * 32 * 1024)
-
 typedef struct _MonoNativeOverlapped MonoNativeOverlapped;
 
 void

+ 10 - 1
mono/metadata/threads-types.h

@@ -59,7 +59,16 @@ typedef void (*MonoThreadCleanupFunc) (MonoNativeThreadId tid);
 /* INFO has type MonoThreadInfo* */
 typedef void (*MonoThreadNotifyPendingExcFunc) (gpointer info);
 
-MonoInternalThread* mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread, guint32 stack_size, MonoError *error);
+typedef enum {
+	MONO_THREAD_CREATE_FLAGS_NONE         = 0x0,
+	MONO_THREAD_CREATE_FLAGS_THREADPOOL   = 0x1,
+	MONO_THREAD_CREATE_FLAGS_DEBUGGER     = 0x2,
+	MONO_THREAD_CREATE_FLAGS_FORCE_CREATE = 0x4,
+	MONO_THREAD_CREATE_FLAGS_SMALL_STACK  = 0x8,
+} MonoThreadCreateFlags;
+
+MonoInternalThread*
+mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error);
 
 void mono_threads_install_cleanup (MonoThreadCleanupFunc func);
 

+ 47 - 26
mono/metadata/threads.c

@@ -648,7 +648,7 @@ static void
 mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, gboolean threadlocal);
 
 static gboolean
-mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean force_domain, gsize *stack_ptr)
+mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean force_domain)
 {
 	MonoThreadInfo *info;
 	MonoInternalThread *internal;
@@ -666,7 +666,6 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
 	internal->tid = MONO_NATIVE_THREAD_ID_TO_UINT (mono_native_thread_id_get ());
 	internal->thread_info = info;
 	internal->small_id = info->small_id;
-	internal->stack_ptr = stack_ptr;
 
 	THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Setting current_object_key to %p", __func__, mono_native_thread_id_get (), internal));
 
@@ -734,6 +733,7 @@ typedef struct {
 	MonoObject *start_delegate_arg;
 	MonoThreadStart start_func;
 	gpointer start_func_arg;
+	gboolean force_attach;
 	gboolean failed;
 	MonoCoopSem registered;
 } StartInfo;
@@ -760,7 +760,7 @@ static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack
 
 	THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Start wrapper", __func__, mono_native_thread_id_get ()));
 
-	if (!mono_thread_attach_internal (thread, FALSE, FALSE, stack_ptr)) {
+	if (!mono_thread_attach_internal (thread, start_info->force_attach, FALSE)) {
 		start_info->failed = TRUE;
 
 		mono_coop_sem_post (&start_info->registered);
@@ -873,11 +873,25 @@ static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack
 	return(0);
 }
 
-static gsize WINAPI start_wrapper(void *data)
+static gsize WINAPI
+start_wrapper (gpointer data)
 {
-	volatile gsize dummy;
+	StartInfo *start_info;
+	MonoThreadInfo *info;
+	gsize res;
+
+	start_info = (StartInfo*) data;
+	g_assert (start_info);
+
+	info = mono_thread_info_attach (&res);
+	info->runtime_thread = TRUE;
+
+	/* Run the actual main function of the thread */
+	res = start_wrapper_internal (start_info, &res);
 
-	return start_wrapper_internal ((StartInfo*) data, (gsize*) &dummy);
+	mono_thread_info_exit (res);
+
+	g_assert_not_reached ();
 }
 
 /*
@@ -888,10 +902,9 @@ static gsize WINAPI start_wrapper(void *data)
  */
 static gboolean
 create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *start_delegate, MonoThreadStart start_func, gpointer start_func_arg,
-	gboolean threadpool_thread, guint32 stack_size, MonoError *error)
+	MonoThreadCreateFlags flags, MonoError *error)
 {
 	StartInfo *start_info = NULL;
-	MonoThreadHandle *thread_handle;
 	MonoNativeThreadId tid;
 	gboolean ret;
 	gsize stack_set_size;
@@ -901,6 +914,15 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	if (start_func)
 		g_assert (!start_delegate);
 
+	if (flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL) {
+		g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER));
+		g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE));
+	}
+	if (flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER) {
+		g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL));
+		g_assert (!(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE));
+	}
+
 	/*
 	 * Join joinable threads to prevent running out of threads since the finalizer
 	 * thread might be blocked/backlogged.
@@ -910,7 +932,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	error_init (error);
 
 	mono_threads_lock ();
-	if (shutting_down) {
+	if (shutting_down && !(flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE)) {
 		mono_threads_unlock ();
 		return FALSE;
 	}
@@ -920,10 +942,12 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	mono_g_hash_table_insert (threads_starting_up, thread, thread);
 	mono_threads_unlock ();
 
-	internal->threadpool_thread = threadpool_thread;
-	if (threadpool_thread)
+	internal->threadpool_thread = flags & MONO_THREAD_CREATE_FLAGS_THREADPOOL;
+	if (internal->threadpool_thread)
 		mono_thread_set_state (internal, ThreadState_Background);
 
+	internal->debugger_thread = flags & MONO_THREAD_CREATE_FLAGS_DEBUGGER;
+
 	start_info = g_new0 (StartInfo, 1);
 	start_info->ref = 2;
 	start_info->thread = thread;
@@ -931,17 +955,16 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	start_info->start_delegate_arg = thread->start_obj;
 	start_info->start_func = start_func;
 	start_info->start_func_arg = start_func_arg;
+	start_info->force_attach = flags & MONO_THREAD_CREATE_FLAGS_FORCE_CREATE;
 	start_info->failed = FALSE;
 	mono_coop_sem_init (&start_info->registered, 0);
 
-	if (stack_size == 0)
+	if (flags != MONO_THREAD_CREATE_FLAGS_SMALL_STACK)
 		stack_set_size = default_stacksize_for_thread (internal);
 	else
 		stack_set_size = 0;
 
-	thread_handle = mono_threads_create_thread (start_wrapper, start_info, &stack_set_size, &tid);
-
-	if (thread_handle == NULL) {
+	if (!mono_thread_platform_create_thread (start_wrapper, start_info, &stack_set_size, &tid)) {
 		/* The thread couldn't be created, so set an exception */
 		mono_threads_lock ();
 		mono_g_hash_table_remove (threads_starting_up, thread);
@@ -966,8 +989,6 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 
 	mono_coop_sem_wait (&start_info->registered, MONO_SEM_FLAGS_NONE);
 
-	mono_threads_close_thread_handle (thread_handle);
-
 	THREAD_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Done launching thread %p (%"G_GSIZE_FORMAT")", __func__, mono_native_thread_id_get (), internal, (gsize)internal->tid));
 
 	ret = !start_info->failed;
@@ -1004,7 +1025,7 @@ guint32 mono_threads_get_default_stacksize (void)
  *   ARG should not be a GC reference.
  */
 MonoInternalThread*
-mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gboolean threadpool_thread, guint32 stack_size, MonoError *error)
+mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, MonoThreadCreateFlags flags, MonoError *error)
 {
 	MonoThread *thread;
 	MonoInternalThread *internal;
@@ -1018,11 +1039,11 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
 
 	LOCK_THREAD (internal);
 
-	res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, threadpool_thread, stack_size, error);
-	return_val_if_nok (error, NULL);
+	res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, flags, error);
 
 	UNLOCK_THREAD (internal);
 
+	return_val_if_nok (error, NULL);
 	return internal;
 }
 
@@ -1037,7 +1058,7 @@ mono_thread_create (MonoDomain *domain, gpointer func, gpointer arg)
 gboolean
 mono_thread_create_checked (MonoDomain *domain, gpointer func, gpointer arg, MonoError *error)
 {
-	return (NULL != mono_thread_create_internal (domain, func, arg, FALSE, 0, error));
+	return (NULL != mono_thread_create_internal (domain, func, arg, MONO_THREAD_CREATE_FLAGS_NONE, error));
 }
 
 MonoThread *
@@ -1053,6 +1074,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 {
 	MonoInternalThread *internal;
 	MonoThread *thread;
+	MonoThreadInfo *info;
 	MonoNativeThreadId tid;
 	gsize stack_ptr;
 
@@ -1063,9 +1085,8 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 		return mono_thread_current ();
 	}
 
-	if (!mono_gc_register_thread (&domain)) {
-		g_error ("Thread %"G_GSIZE_FORMAT" calling into managed code is not registered with the GC. On UNIX, this can be fixed by #include-ing <gc.h> before <pthread.h> in the file containing the thread creation code.", mono_native_thread_id_get ());
-	}
+	info = mono_thread_info_attach (&stack_ptr);
+	g_assert (info);
 
 	tid=mono_native_thread_id_get ();
 
@@ -1073,7 +1094,7 @@ mono_thread_attach_full (MonoDomain *domain, gboolean force_attach)
 
 	thread = create_thread_object (domain, internal);
 
-	if (!mono_thread_attach_internal (thread, force_attach, TRUE, &stack_ptr)) {
+	if (!mono_thread_attach_internal (thread, force_attach, TRUE)) {
 		/* Mono is shutting down, so just wait for the end */
 		for (;;)
 			mono_thread_info_sleep (10000, NULL);
@@ -1345,7 +1366,7 @@ ves_icall_System_Threading_Thread_Thread_internal (MonoThread *this_obj,
 		return this_obj;
 	}
 
-	res = create_thread (this_obj, internal, start, NULL, NULL, FALSE, 0, &error);
+	res = create_thread (this_obj, internal, start, NULL, NULL, MONO_THREAD_CREATE_FLAGS_NONE, &error);
 	if (!res) {
 		mono_error_cleanup (&error);
 		UNLOCK_THREAD (internal);

+ 13 - 9
mono/mini/aot-compiler.c

@@ -7892,14 +7892,13 @@ compile_method (MonoAotCompile *acfg, MonoMethod *method)
 static mono_thread_start_return_t WINAPI
 compile_thread_main (gpointer user_data)
 {
-	MonoDomain *domain = ((MonoDomain **)user_data) [0];
-	MonoAotCompile *acfg = ((MonoAotCompile **)user_data) [1];
-	GPtrArray *methods = ((GPtrArray **)user_data) [2];
+	MonoAotCompile *acfg = ((MonoAotCompile **)user_data) [0];
+	GPtrArray *methods = ((GPtrArray **)user_data) [1];
 	int i;
 
 	MonoError error;
-	MonoThread *thread = mono_thread_attach (domain);
-	mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "AOT compiler"), TRUE, FALSE, &error);
+	MonoInternalThread *internal = mono_thread_internal_current ();
+	mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "AOT compiler"), TRUE, FALSE, &error);
 	mono_error_assert_ok (&error);
 
 	for (i = 0; i < methods->len; ++i)
@@ -9869,6 +9868,9 @@ compile_methods (MonoAotCompile *acfg)
 			methods [i] = (MonoMethod *)g_ptr_array_index (acfg->methods, i);
 		i = 0;
 		while (i < methods_len) {
+			MonoError error;
+			MonoInternalThread *thread;
+
 			frag = g_ptr_array_new ();
 			for (j = 0; j < len; ++j) {
 				if (i < methods_len) {
@@ -9878,11 +9880,13 @@ compile_methods (MonoAotCompile *acfg)
 			}
 
 			user_data = g_new0 (gpointer, 3);
-			user_data [0] = mono_domain_get ();
-			user_data [1] = acfg;
-			user_data [2] = frag;
+			user_data [0] = acfg;
+			user_data [1] = frag;
 			
-			thread_handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, NULL, NULL);
+			thread = mono_thread_create_internal (mono_domain_get (), compile_thread_main, (gpointer) user_data, MONO_THREAD_CREATE_FLAGS_NONE, &error);
+			mono_error_assert_ok (&error);
+
+			thread_handle = mono_threads_open_thread_handle (thread->handle);
 			g_ptr_array_add (threads, thread_handle);
 		}
 		g_free (methods);

+ 24 - 13
mono/mini/debugger-agent.c

@@ -818,7 +818,13 @@ register_socket_transport (void);
 static inline gboolean
 is_debugger_thread (void)
 {
-	return mono_native_thread_id_equals (mono_native_thread_id_get (), debugger_thread_id);
+	MonoInternalThread *internal;
+
+	internal = mono_thread_internal_current ();
+	if (!internal)
+		return FALSE;
+
+	return internal->debugger_thread;
 }
 
 static int
@@ -1634,7 +1640,13 @@ stop_debugger_thread (void)
 static void
 start_debugger_thread (void)
 {
-	debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, NULL, NULL);
+	MonoError error;
+	MonoInternalThread *thread;
+
+	thread = mono_thread_create_internal (mono_get_root_domain (), debugger_thread, NULL, MONO_THREAD_CREATE_FLAGS_DEBUGGER, &error);
+	mono_error_assert_ok (&error);
+
+	debugger_thread_handle = mono_threads_open_thread_handle (thread->handle);
 	g_assert (debugger_thread_handle);
 }
 
@@ -2682,7 +2694,7 @@ notify_thread (gpointer key, gpointer value, gpointer user_data)
 	DebuggerTlsData *tls = (DebuggerTlsData *)value;
 	MonoNativeThreadId tid = MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid);
 
-	if (mono_native_thread_id_equals (mono_native_thread_id_get (), tid) || tls->terminated)
+	if (mono_thread_internal_is_current (thread) || tls->terminated)
 		return;
 
 	DEBUG_PRINTF (1, "[%p] Interrupting %p...\n", (gpointer) (gsize) mono_native_thread_id_get (), (gpointer)tid);
@@ -2954,7 +2966,7 @@ count_thread (gpointer key, gpointer value, gpointer user_data)
 {
 	DebuggerTlsData *tls = (DebuggerTlsData *)value;
 
-	if (!tls->suspended && !tls->terminated)
+	if (!tls->suspended && !tls->terminated && !mono_thread_internal_is_current (tls->thread))
 		*(int*)user_data = *(int*)user_data + 1;
 }
 
@@ -3248,8 +3260,8 @@ emit_appdomain_load (gpointer key, gpointer value, gpointer user_data)
 static void
 emit_thread_start (gpointer key, gpointer value, gpointer user_data)
 {
-	if (!mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (GPOINTER_TO_UINT (key)), debugger_thread_id))
-		process_profiler_event (EVENT_KIND_THREAD_START, value);
+	g_assert (!mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (GPOINTER_TO_UINT (key)), debugger_thread_id));
+	process_profiler_event (EVENT_KIND_THREAD_START, value);
 }
 
 /*
@@ -3810,7 +3822,7 @@ thread_startup (MonoProfiler *prof, uintptr_t tid)
 	MonoInternalThread *old_thread;
 	DebuggerTlsData *tls;
 
-	if (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), debugger_thread_id))
+	if (is_debugger_thread ())
 		return;
 
 	g_assert (mono_native_thread_id_equals (MONO_UINT_TO_NATIVE_THREAD_ID (tid), MONO_UINT_TO_NATIVE_THREAD_ID (thread->tid)));
@@ -3889,8 +3901,7 @@ thread_end (MonoProfiler *prof, uintptr_t tid)
 	if (thread) {
 		DEBUG_PRINTF (1, "[%p] Thread terminated, obj=%p, tls=%p.\n", (gpointer)tid, thread, tls);
 
-		if (mono_native_thread_id_equals (mono_native_thread_id_get (), MONO_UINT_TO_NATIVE_THREAD_ID (tid))
-		     && !mono_native_tls_get_value (debugger_tls_id)
+		if (mono_thread_internal_is_current (thread) && !mono_native_tls_get_value (debugger_tls_id)
 		) {
 			/*
 			 * This can happen on darwin since we deregister threads using pthread dtors.
@@ -10131,12 +10142,12 @@ debugger_thread (void *arg)
 
 	debugger_thread_id = mono_native_thread_id_get ();
 
-	MonoThread *thread = mono_thread_attach (mono_get_root_domain ());
-	mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Debugger agent"), TRUE, FALSE, &error);
+	MonoInternalThread *internal = mono_thread_internal_current ();
+	mono_thread_set_name_internal (internal, mono_string_new (mono_domain_get (), "Debugger agent"), TRUE, FALSE, &error);
 	mono_error_assert_ok (&error);
 
-	thread->internal_thread->state |= ThreadState_Background;
-	thread->internal_thread->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
+	internal->state |= ThreadState_Background;
+	internal->flags |= MONO_THREAD_FLAG_DONT_MANAGE;
 
 	if (agent_config.defer) {
 		if (!wait_for_attach ()) {

+ 0 - 6
mono/utils/mono-threads-haiku.c

@@ -6,12 +6,6 @@
 #include <pthread.h>
 #include <os/kernel/OS.h>
 
-void
-mono_threads_platform_reset_priority(pthread_attr_t *attr)
-{
-	/* FIXME: Implement this on Haiku */
-}
-
 void
 mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize)
 {

+ 24 - 68
mono/utils/mono-threads-posix.c

@@ -35,67 +35,17 @@ extern int tkill (pid_t tid, int signal);
 
 #include <sys/resource.h>
 
-#ifdef MONO_THREADS_PLATFORM_HAS_ATTR_SETSCHED
-void
-mono_threads_platform_reset_priority (pthread_attr_t *attr)
-{
-	struct sched_param param;
-	gint res;
-	gint policy;
-
-	memset (&param, 0, sizeof (param));
-
-	res = pthread_attr_getschedpolicy (attr, &policy);
-	if (res != 0)
-		g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
-
-#ifdef _POSIX_PRIORITY_SCHEDULING
-	gint max, min;
-
-	/* Necessary to get valid priority range */
-
-	min = sched_get_priority_min (policy);
-	max = sched_get_priority_max (policy);
-
-	if (max > 0 && min >= 0 && max > min)
-		param.sched_priority = (max - min) / 2 + min;
-	else
-#endif
-	{
-		switch (policy) {
-		case SCHED_FIFO:
-		case SCHED_RR:
-			param.sched_priority = 50;
-			break;
-#ifdef SCHED_BATCH
-		case SCHED_BATCH:
-#endif
-		case SCHED_OTHER:
-			param.sched_priority = 0;
-			break;
-		default:
-			g_warning ("%s: unknown policy %d", __func__, policy);
-			return;
-		}
-	}
-
-	res = pthread_attr_setschedparam (attr, &param);
-	if (res != 0)
-		g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-#endif
-
-int
-mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid)
+gboolean
+mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid)
 {
 	pthread_attr_t attr;
 	pthread_t thread;
 	gint res;
 	gsize set_stack_size;
-	gsize min_stack_size;
 
 	res = pthread_attr_init (&attr);
-	g_assert (!res);
+	if (res != 0)
+		g_error ("%s: pthread_attr_init failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
 
 	if (stack_size)
 		set_stack_size = *stack_size;
@@ -120,28 +70,34 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_
 #endif
 
 	res = pthread_attr_setstacksize (&attr, set_stack_size);
-	g_assert (!res);
+	if (res != 0)
+		g_error ("%s: pthread_attr_setstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
 
-	mono_threads_platform_reset_priority (&attr);
-
-	if (stack_size) {
-		res = pthread_attr_getstacksize (&attr, &min_stack_size);
+	/* Actually start the thread */
+	res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
+	if (res) {
+		res = pthread_attr_destroy (&attr);
 		if (res != 0)
-			g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", g_strerror (res), res);
+			g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
 
-		*stack_size = min_stack_size;
+		return FALSE;
 	}
 
-	/* Actually start the thread */
-	res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
-	if (res)
-		return -1;
+	if (tid)
+		*tid = thread;
+
+	if (stack_size) {
+		res = pthread_attr_getstacksize (&attr, stack_size);
+		if (res != 0)
+			g_error ("%s: pthread_attr_getstacksize failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
+	}
 
-	if (out_tid)
-		*out_tid = thread;
+	res = pthread_attr_destroy (&attr);
+	if (res != 0)
+		g_error ("%s: pthread_attr_destroy failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
 
-	return 0;
+	return TRUE;
 }
 
 void

+ 6 - 6
mono/utils/mono-threads-windows.c

@@ -183,22 +183,22 @@ mono_threads_suspend_get_abort_signal (void)
 
 #if defined (HOST_WIN32)
 
-int
-mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid)
+gboolean
+mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *tid)
 {
 	HANDLE result;
 	DWORD thread_id;
 
 	result = CreateThread (NULL, stack_size ? *stack_size : 0, (LPTHREAD_START_ROUTINE) thread_fn, thread_data, 0, &thread_id);
 	if (!result)
-		return -1;
+		return FALSE;
 
 	/* A new handle is open when attaching
 	 * the thread, so we don't need this one */
 	CloseHandle (result);
 
-	if (out_tid)
-		*out_tid = thread_id;
+	if (tid)
+		*tid = thread_id;
 
 	if (stack_size) {
 		// TOOD: Use VirtualQuery to get correct value 
@@ -206,7 +206,7 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_
 		*stack_size = 2 * 1024 * 1024;
 	}
 
-	return 0;
+	return TRUE;
 }
 
 

+ 0 - 94
mono/utils/mono-threads.c

@@ -1118,100 +1118,6 @@ mono_thread_info_is_async_context (void)
 		return FALSE;
 }
 
-typedef struct {
-	MonoRefCount ref;
-	MonoThreadStart start_routine;
-	gpointer start_routine_arg;
-	MonoCoopSem registered;
-	MonoThreadHandle *handle;
-} CreateThreadData;
-
-static void
-create_thread_data_destroy (gpointer data)
-{
-	CreateThreadData *thread_data;
-
-	thread_data = (CreateThreadData*) data;
-
-	mono_coop_sem_destroy (&thread_data->registered);
-	g_free (thread_data);
-}
-
-static gsize WINAPI
-inner_start_thread (gpointer data)
-{
-	CreateThreadData *thread_data;
-	MonoThreadInfo *info;
-	MonoThreadStart start_routine;
-	gpointer start_routine_arg;
-	gsize start_routine_res;
-	gsize dummy;
-
-	thread_data = (CreateThreadData*) data;
-	g_assert (thread_data);
-
-	start_routine = thread_data->start_routine;
-	start_routine_arg = thread_data->start_routine_arg;
-
-	info = mono_thread_info_attach (&dummy);
-	info->runtime_thread = TRUE;
-
-	thread_data->handle = mono_threads_open_thread_handle (info->handle);
-
-	mono_coop_sem_post (&thread_data->registered);
-
-	mono_refcount_dec (thread_data);
-
-	/* thread_data is not valid anymore */
-	thread_data = NULL;
-
-	/* Run the actual main function of the thread */
-	start_routine_res = start_routine (start_routine_arg);
-
-	mono_thread_info_exit (start_routine_res);
-
-	g_assert_not_reached ();
-}
-
-/*
- * mono_threads_create_thread:
- *
- *   Create a new thread executing START with argument ARG. Store its id into OUT_TID.
- * Returns: a windows or io-layer handle for the thread.
- */
-MonoThreadHandle*
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize * const stack_size, MonoNativeThreadId *out_tid)
-{
-	CreateThreadData *thread_data;
-	gint res;
-	MonoThreadHandle *ret;
-
-	thread_data = g_new0 (CreateThreadData, 1);
-	mono_refcount_init (thread_data, create_thread_data_destroy);
-	thread_data->start_routine = start;
-	thread_data->start_routine_arg = arg;
-	mono_coop_sem_init (&thread_data->registered, 0);
-
-	res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) mono_refcount_inc (thread_data), stack_size, out_tid);
-	if (res != 0) {
-		/* ref is not going to be decremented in inner_start_thread */
-		mono_refcount_dec (thread_data);
-		ret = NULL;
-		goto done;
-	}
-
-	res = mono_coop_sem_wait (&thread_data->registered, MONO_SEM_FLAGS_NONE);
-	g_assert (res == 0);
-
-	ret = thread_data->handle;
-	g_assert (ret);
-
-done:
-	mono_refcount_dec (thread_data);
-
-	return ret;
-}
-
 /*
  * mono_thread_info_get_stack_bounds:
  *

+ 4 - 7
mono/utils/mono-threads.h

@@ -408,9 +408,6 @@ mono_thread_info_describe_interrupt_token (THREAD_INFO_TYPE *info, GString *text
 gboolean
 mono_thread_info_is_live (THREAD_INFO_TYPE *info);
 
-MonoThreadHandle*
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize * const stack_size, MonoNativeThreadId *out_tid);
-
 int
 mono_threads_get_max_stack_size (void);
 
@@ -481,10 +478,10 @@ gint mono_threads_suspend_get_suspend_signal (void);
 gint mono_threads_suspend_get_restart_signal (void);
 gint mono_threads_suspend_get_abort_signal (void);
 
-#if defined(USE_POSIX_BACKEND)
-void mono_threads_platform_reset_priority (pthread_attr_t *attr);
-#endif /* defined(USE_POSIX_BACKEND) */
-int mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data, gsize* const stack_size, MonoNativeThreadId *out_tid);
+gboolean
+mono_thread_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_data,
+	gsize* const stack_size, MonoNativeThreadId *tid);
+
 void mono_threads_platform_get_stack_bounds (guint8 **staddr, size_t *stsize);
 void mono_threads_platform_init (void);
 gboolean mono_threads_platform_in_critical_region (MonoNativeThreadId tid);