Merge pull request #3328 from BrzVlad/finalizer-thread-exited2
[mono.git] / mono / utils / mono-threads-posix.c
index 54f183e58f03659937730f70797d3de5b411c0db..cb218f5c14d3d3e88957435fb7c5b6d1c5aea175 100644 (file)
@@ -41,6 +41,7 @@ typedef struct {
        void *(*start_routine)(void*);
        void *arg;
        int flags;
+       gint32 priority;
        MonoCoopSem registered;
        HANDLE handle;
 } StartInfo;
@@ -60,8 +61,7 @@ inner_start_thread (void *arg)
        /* Register the thread with the io-layer */
        handle = wapi_create_thread_handle ();
        if (!handle) {
-               res = mono_coop_sem_post (&(start_info->registered));
-               g_assert (!res);
+               mono_coop_sem_post (&(start_info->registered));
                return NULL;
        }
        start_info->handle = handle;
@@ -71,14 +71,15 @@ inner_start_thread (void *arg)
        info->runtime_thread = TRUE;
        info->handle = handle;
 
+       wapi_init_thread_info_priority(handle, start_info->priority);
+
        if (flags & CREATE_SUSPENDED) {
                info->create_suspended = TRUE;
                mono_coop_sem_init (&info->create_suspended_sem, 0);
        }
 
        /* start_info is not valid after this */
-       res = mono_coop_sem_post (&(start_info->registered));
-       g_assert (!res);
+       mono_coop_sem_post (&(start_info->registered));
        start_info = NULL;
 
        if (flags & CREATE_SUSPENDED) {
@@ -96,17 +97,20 @@ inner_start_thread (void *arg)
 }
 
 HANDLE
-mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid)
+mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
 {
        pthread_attr_t attr;
        int res;
        pthread_t thread;
        StartInfo start_info;
+       guint32 stack_size;
+       int policy;
+       struct sched_param sp;
 
        res = pthread_attr_init (&attr);
        g_assert (!res);
 
-       if (stack_size == 0) {
+       if (tp->stack_size == 0) {
 #if HAVE_VALGRIND_MEMCHECK_H
                if (RUNNING_ON_VALGRIND)
                        stack_size = 1 << 20;
@@ -115,7 +119,8 @@ mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer
 #else
                stack_size = (SIZEOF_VOID_P / 4) * 1024 * 1024;
 #endif
-       }
+       } else
+               stack_size = tp->stack_size;
 
 #ifdef PTHREAD_STACK_MIN
        if (stack_size < PTHREAD_STACK_MIN)
@@ -127,10 +132,20 @@ mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer
        g_assert (!res);
 #endif
 
+       /*
+        * For policies that respect priorities set the prirority for the new thread
+        */ 
+       pthread_getschedparam(pthread_self(), &policy, &sp);
+       if ((policy == SCHED_FIFO) || (policy == SCHED_RR)) {
+               sp.sched_priority = wapi_thread_priority_to_posix_priority (tp->priority, policy);
+               res = pthread_attr_setschedparam (&attr, &sp);
+       }
+
        memset (&start_info, 0, sizeof (StartInfo));
        start_info.start_routine = (void *(*)(void *)) start_routine;
        start_info.arg = arg;
-       start_info.flags = creation_flags;
+       start_info.flags = tp->creation_flags;
+       start_info.priority = tp->priority;
        mono_coop_sem_init (&(start_info.registered), 0);
 
        /* Actually start the thread */
@@ -277,9 +292,36 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
 }
 
 void
-mono_threads_core_set_name (MonoNativeThreadId tid, const char *name)
+mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
 {
-#if defined (HAVE_PTHREAD_SETNAME_NP) && !defined (__MACH__)
+#ifdef __MACH__
+       /*
+        * We can't set the thread name for other threads, but we can at least make
+        * it work for threads that try to change their own name.
+        */
+       if (tid != mono_native_thread_id_get ())
+               return;
+
+       if (!name) {
+               pthread_setname_np ("");
+       } else {
+               char n [63];
+
+               strncpy (n, name, 63);
+               n [62] = '\0';
+               pthread_setname_np (n);
+       }
+#elif defined (__NetBSD__)
+       if (!name) {
+               pthread_setname_np (tid, "%s", (void*)"");
+       } else {
+               char n [PTHREAD_MAX_NAMELEN_NP];
+
+               strncpy (n, name, PTHREAD_MAX_NAMELEN_NP);
+               n [PTHREAD_MAX_NAMELEN_NP - 1] = '\0';
+               pthread_setname_np (tid, "%s", (void*)n);
+       }
+#elif defined (HAVE_PTHREAD_SETNAME_NP)
        if (!name) {
                pthread_setname_np (tid, "");
        } else {