From 30d60224a85b2e36406bf58e9ab7bfe7ffa6509f Mon Sep 17 00:00:00 2001 From: Ludovic Henry Date: Thu, 2 Mar 2017 18:47:41 -0500 Subject: [PATCH] [threads] Remove mono_threads_create_thread (#4411) --- mcs/class/corlib/System.Threading/Thread.cs | 2 +- mono/metadata/appdomain.c | 23 ++--- mono/metadata/attach.c | 25 +++--- mono/metadata/gc.c | 2 +- mono/metadata/object-internals.h | 2 +- mono/metadata/threadpool-io.c | 2 +- mono/metadata/threadpool-worker-default.c | 4 +- mono/metadata/threadpool.h | 2 - mono/metadata/threads-types.h | 11 ++- mono/metadata/threads.c | 73 ++++++++++------ mono/mini/aot-compiler.c | 22 +++-- mono/mini/debugger-agent.c | 37 +++++--- mono/utils/mono-threads-haiku.c | 6 -- mono/utils/mono-threads-posix.c | 92 ++++++-------------- mono/utils/mono-threads-windows.c | 12 +-- mono/utils/mono-threads.c | 94 --------------------- mono/utils/mono-threads.h | 11 +-- 17 files changed, 161 insertions(+), 259 deletions(-) diff --git a/mcs/class/corlib/System.Threading/Thread.cs b/mcs/class/corlib/System.Threading/Thread.cs index 9145dfd158e..6d96fe1b367 100644 --- a/mcs/class/corlib/System.Threading/Thread.cs +++ b/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 diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 0a46dc5d4a6..151f40bbaf8 100644 --- a/mono/metadata/appdomain.c +++ b/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) { diff --git a/mono/metadata/attach.c b/mono/metadata/attach.c index 1f2e0fd103d..72330bbc4fb 100644 --- a/mono/metadata/attach.c +++ b/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; diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index 7402096d704..499e3840063 100644 --- a/mono/metadata/gc.c +++ b/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); } diff --git a/mono/metadata/object-internals.h b/mono/metadata/object-internals.h index c7ef8233bf7..958d25ac914 100644 --- a/mono/metadata/object-internals.h +++ b/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; diff --git a/mono/metadata/threadpool-io.c b/mono/metadata/threadpool-io.c index 4f4fa7b1559..4e3b30f0115 100644 --- a/mono/metadata/threadpool-io.c +++ b/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)); } diff --git a/mono/metadata/threadpool-worker-default.c b/mono/metadata/threadpool-worker-default.c index 5fc716a74e7..c1f4a878e99 100644 --- a/mono/metadata/threadpool-worker-default.c +++ b/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); diff --git a/mono/metadata/threadpool.h b/mono/metadata/threadpool.h index df17997b16c..a628e331131 100644 --- a/mono/metadata/threadpool.h +++ b/mono/metadata/threadpool.h @@ -7,8 +7,6 @@ #include #include -#define SMALL_STACK (sizeof (gpointer) * 32 * 1024) - typedef struct _MonoNativeOverlapped MonoNativeOverlapped; void diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index 75cef7ef363..cc1ee27d936 100644 --- a/mono/metadata/threads-types.h +++ b/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); diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index 1c47c444587..5f290cf3dc2 100644 --- a/mono/metadata/threads.c +++ b/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 before 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); diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 947e4e33d6f..c3ef0287892 100644 --- a/mono/mini/aot-compiler.c +++ b/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); diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 088bfceea82..e18cb98d643 100644 --- a/mono/mini/debugger-agent.c +++ b/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 ()) { diff --git a/mono/utils/mono-threads-haiku.c b/mono/utils/mono-threads-haiku.c index 231ff3be8f4..e5c3563902a 100644 --- a/mono/utils/mono-threads-haiku.c +++ b/mono/utils/mono-threads-haiku.c @@ -6,12 +6,6 @@ #include #include -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) { diff --git a/mono/utils/mono-threads-posix.c b/mono/utils/mono-threads-posix.c index be4be154301..d978c538ae9 100644 --- a/mono/utils/mono-threads-posix.c +++ b/mono/utils/mono-threads-posix.c @@ -35,67 +35,17 @@ extern int tkill (pid_t tid, int signal); #include -#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 (¶m, 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, ¶m); - 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 diff --git a/mono/utils/mono-threads-windows.c b/mono/utils/mono-threads-windows.c index 91ce0f6ea49..b350187e7e7 100644 --- a/mono/utils/mono-threads-windows.c +++ b/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; } diff --git a/mono/utils/mono-threads.c b/mono/utils/mono-threads.c index 30ea1db19ad..a468cd9383d 100644 --- a/mono/utils/mono-threads.c +++ b/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: * diff --git a/mono/utils/mono-threads.h b/mono/utils/mono-threads.h index f0410e3132e..867946071c3 100644 --- a/mono/utils/mono-threads.h +++ b/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); -- 2.25.1