[threads] Remove mono_threads_create_thread (#4411)
authorLudovic Henry <ludovic@xamarin.com>
Thu, 2 Mar 2017 23:47:41 +0000 (18:47 -0500)
committerGitHub <noreply@github.com>
Thu, 2 Mar 2017 23:47:41 +0000 (18:47 -0500)
17 files changed:
mcs/class/corlib/System.Threading/Thread.cs
mono/metadata/appdomain.c
mono/metadata/attach.c
mono/metadata/gc.c
mono/metadata/object-internals.h
mono/metadata/threadpool-io.c
mono/metadata/threadpool-worker-default.c
mono/metadata/threadpool.h
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/mini/aot-compiler.c
mono/mini/debugger-agent.c
mono/utils/mono-threads-haiku.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h

index 9145dfd158e085542eb0216c3a2570a254b8bec5..6d96fe1b3673632ac00b57d23b4fc1c1011be851 100644 (file)
@@ -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
index 0a46dc5d4a656591356cda09cc7d3b3f53e78f4a..151f40bbaf852f9506efcda5d4e8c70027dd63aa 100644 (file)
@@ -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) {
index 1f2e0fd103d93fc73768878b4f0c3181f40de996..72330bbc4fbac5b967452135f960a34d304fab52 100644 (file)
@@ -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;
index 7402096d704dfd5bf71ba5d1ac5d7b8801152365..499e3840063685256683cf588a7c2b5f04bac232 100644 (file)
@@ -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);
 }
 
index c7ef8233bf784883c91ae60d878759d5a63c4df7..958d25ac914fe47c075d4a2722da3d76b48534b9 100644 (file)
@@ -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;
index 4f4fa7b1559c202ec6d0ef11435e43504759831c..4e3b30f011541330aa48beb58265f4b6d68a9d17 100644 (file)
@@ -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));
 }
 
index 5fc716a74e73e87999bc0e124fdb9a19b64f1c9f..c1f4a878e9916f65673e6a93b09aa8cad22407bc 100644 (file)
@@ -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);
index df17997b16c567521f68f2829d197817cd6cb88d..a628e3311313b293480abd8dee3523f7645ba0fc 100644 (file)
@@ -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
index 75cef7ef363b6918751e492c361fdff983e0208c..cc1ee27d936dabcb0cc2fb0852465b46658f842a 100644 (file)
@@ -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);
 
index 1c47c4445871cb0f65d0ddbe6fe9710b52d870bd..5f290cf3dc253021723fcc2acd6496021cb021b8 100644 (file)
@@ -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);
index 947e4e33d6fdbf9770fd1886413e09ac27e0a973..c3ef028789288d800198496a68031222426e2cdf 100644 (file)
@@ -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);
index 088bfceea8261377c8423eefc3dabb1f6c94a573..e18cb98d643bd015f474be8bec56aa36e03706b6 100644 (file)
@@ -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 ()) {
index 231ff3be8f4299e6d13640a00ae10da24f2128d8..e5c3563902ab6c79a6107c8a0e8b55e291764a48 100644 (file)
@@ -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)
 {
index be4be1543011029f7ff2ec1b76d48172a513085b..d978c538ae9b2d934a946088a145d8c47e379bc8 100644 (file)
@@ -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
index 91ce0f6ea4942b68469d657111245c025499675e..b350187e7e7a795a43e4f45cac2551ad0391ce09 100644 (file)
@@ -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;
 }
 
 
index 30ea1db19ad2af0ee2ca08babf7ed8d72aff2173..a468cd9383db908131ff4eaf1f02de369c3ca701 100644 (file)
@@ -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:
  *
index f0410e3132e0ae0cd8a96e1ef47d3a5a7f060263..867946071c3aa21c16923060f88cd4fe3e383eb0 100644 (file)
@@ -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);