[io-layer] Extract GetThreadPriority and SetThreadPriority
authorLudovic Henry <ludovic@xamarin.com>
Thu, 7 Jul 2016 17:13:11 +0000 (19:13 +0200)
committerLudovic Henry <ludovic@xamarin.com>
Thu, 4 Aug 2016 13:41:45 +0000 (15:41 +0200)
14 files changed:
mcs/class/corlib/System.Threading/Thread.cs
mono/io-layer/threads.h
mono/io-layer/wapi-remap.h
mono/io-layer/wthreads.c
mono/metadata/appdomain.c
mono/metadata/attach.c
mono/metadata/threads-types.h
mono/metadata/threads.c
mono/mini/aot-compiler.c
mono/mini/debugger-agent.c
mono/utils/mono-threads-posix.c
mono/utils/mono-threads-windows.c
mono/utils/mono-threads.c
mono/utils/mono-threads.h

index de7889e827d74afd5861cbad1522b865d41fa8fb..d46999b767b535c04572e9cf6008f2d6fcdee221 100644 (file)
@@ -116,7 +116,7 @@ namespace System.Threading {
                private InternalThread internal_thread;
                object m_ThreadStartArg;
                object pending_exception;
-               int priority;
+               int priority = (int) ThreadPriority.Normal;
                #endregion
 #pragma warning restore 414
 
index a293ff22d792103b1099139848d01d456d1256ff..e84a63b1d1dd0312dd033c47a35614c4cb5b083b 100644 (file)
@@ -32,20 +32,6 @@ typedef struct {
        GPtrArray *owned_mutexes;
        gint32 priority;
 } MonoW32HandleThread;
-typedef enum {
-       THREAD_PRIORITY_LOWEST = -2,
-       THREAD_PRIORITY_BELOW_NORMAL = -1,
-       THREAD_PRIORITY_NORMAL = 0,
-       THREAD_PRIORITY_ABOVE_NORMAL = 1,
-       THREAD_PRIORITY_HIGHEST = 2
-} WapiThreadPriority;
-
-extern gint32 GetThreadPriority (gpointer handle);
-extern gboolean SetThreadPriority (gpointer handle, gint32 priority);
-
-extern int wapi_thread_priority_to_posix_priority (WapiThreadPriority, int);
-extern void wapi_init_thread_info_priority (gpointer, gint32);
 
 G_END_DECLS
 #endif /* _WAPI_THREADS_H_ */
index d8c4aaccb0095e997d483aa17ca2ea36146d476c..b848a483c7030aad42af1650541355d16f260836 100644 (file)
@@ -99,7 +99,5 @@
 #define WaitForMultipleObjects wapi_WaitForMultipleObjects
 #define WaitForMultipleObjectsEx wapi_WaitForMultipleObjectsEx
 #define WaitForInputIdle wapi_WaitForInputIdle
-#define GetThreadPriority wapi_GetThreadPriority
-#define SetThreadPriority wapi_SetThreadPriority
 
 #endif /* __WAPI_REMAP_H__ */
index e7f818f0e627c626e5659971d6db5eca33288fbd..845dccb44e3a84ef61bbafc871149a928699176c 100644 (file)
@@ -83,221 +83,3 @@ void
 _wapi_thread_cleanup (void)
 {
 }
-
-/**
- * wapi_init_thread_info_priority:
- * @param handle: The thread handle to set.
- * @param priority: Priority to initialize with
- *
- *   Initialize the priority field of the thread info
- */
-void
-wapi_init_thread_info_priority (gpointer handle, gint32 priority)
-{
-       MonoW32HandleThread *thread_handle = NULL;
-       gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
-                                 (gpointer *)&thread_handle);
-                                 
-       if (ok == TRUE)
-               thread_handle->priority = priority;
-}
-
-/**
- * _wapi_thread_posix_priority_to_priority:
- *
- *   Convert a POSIX priority to a WapiThreadPriority.
- * sched_priority is a POSIX priority,
- * policy is the current scheduling policy
- */
-static WapiThreadPriority 
-_wapi_thread_posix_priority_to_priority (int sched_priority, int policy)
-{
-/* Necessary to get valid priority range */
-#ifdef _POSIX_PRIORITY_SCHEDULING
-       int max,
-           min,
-           i,
-           priority,
-           chunk;
-       WapiThreadPriority priorities[] = {
-               THREAD_PRIORITY_LOWEST,
-               THREAD_PRIORITY_LOWEST,
-               THREAD_PRIORITY_BELOW_NORMAL,
-               THREAD_PRIORITY_NORMAL,
-               THREAD_PRIORITY_ABOVE_NORMAL,
-               THREAD_PRIORITY_HIGHEST,
-               THREAD_PRIORITY_HIGHEST
-       };
-           
-       max = sched_get_priority_max (policy);
-       min = sched_get_priority_min (policy);
-       
-       /* Partition priority range linearly, 
-          assign each partition a thread priority */
-       if (max != min && 0 <= max && 0 <= min) {
-               for (i=1, priority=min, chunk=(max-min)/7; 
-                    i<6 && sched_priority > priority;
-                    ++i) {
-                       priority += chunk;
-               }
-               
-               if (max <= priority)
-               {
-                       return (THREAD_PRIORITY_HIGHEST);
-               }
-               else
-               {
-                       return (priorities[i-1]);
-               }
-       }
-#endif
-
-       return (THREAD_PRIORITY_NORMAL);
-}
-
-/**
- * wapi_thread_priority_to_posix_priority:
- *
- *   Convert a WapiThreadPriority to a POSIX priority.
- * priority is a WapiThreadPriority,
- * policy is the current scheduling policy
- */
-int 
-wapi_thread_priority_to_posix_priority (WapiThreadPriority priority, int policy)
-{
-/* Necessary to get valid priority range */
-#ifdef _POSIX_PRIORITY_SCHEDULING
-       int max,
-           min,
-           posix_priority,
-           i;
-       WapiThreadPriority priorities[] = {
-               THREAD_PRIORITY_LOWEST,
-               THREAD_PRIORITY_LOWEST,
-               THREAD_PRIORITY_BELOW_NORMAL,
-               THREAD_PRIORITY_NORMAL,
-               THREAD_PRIORITY_ABOVE_NORMAL,
-               THREAD_PRIORITY_HIGHEST,
-               THREAD_PRIORITY_HIGHEST
-       };
-       
-       max = sched_get_priority_max (policy);
-       min = sched_get_priority_min (policy);
-
-       /* Partition priority range linearly, 
-          numerically approximate matching ThreadPriority */
-       if (max != min && 0 <= max && 0 <= min) {
-               for (i=0; i<7; ++i) {
-                       if (priorities[i] == priority) {
-                               posix_priority = min + ((max-min)/7) * i;
-                               if (max < posix_priority)
-                               {
-                                       return max;
-                               }
-                               else {
-                                       return posix_priority;
-                               }
-                       }
-               }
-       }
-#endif
-
-       switch (policy) {
-               case SCHED_FIFO:
-               case SCHED_RR:
-                       return 50;
-#ifdef SCHED_BATCH
-               case SCHED_BATCH:
-#endif
-               case SCHED_OTHER:
-                       return 0;
-               default:
-                       return -1;
-       }
-}
-
-/**
- * GetThreadPriority:
- * @param handle: The thread handle to query.
- *
- * Gets the priority of the given thread.
- * @return: A MonoThreadPriority approximating the current POSIX 
- * thread priority, or THREAD_PRIORITY_NORMAL on error.
- */
-gint32 
-GetThreadPriority (gpointer handle)
-{
-       MonoW32HandleThread *thread_handle = NULL;
-       int policy;
-       struct sched_param param;
-       gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
-                                 (gpointer *)&thread_handle);
-                                 
-       if (ok == FALSE)
-               return (THREAD_PRIORITY_NORMAL);
-       
-       switch (pthread_getschedparam (thread_handle->id, &policy, &param)) {
-               case 0:
-                       if ((policy == SCHED_FIFO) || (policy == SCHED_RR))
-                               return (_wapi_thread_posix_priority_to_priority (param.sched_priority, policy));
-                       else
-                               return (thread_handle->priority);
-               case ESRCH:
-                       g_warning ("pthread_getschedparam: error looking up thread id %x", (gsize)thread_handle->id);
-       }
-       
-       return (THREAD_PRIORITY_NORMAL);
-}
-
-/**
- * SetThreadPriority:
- * @param handle: The thread handle to query.
- * @param priority: The priority to give to the thread.
- *
- * Sets the priority of the given thread.
- * @return: TRUE on success, FALSE on failure or error.
- */
-gboolean 
-SetThreadPriority (gpointer handle, gint32 priority)
-{
-       MonoW32HandleThread *thread_handle = NULL;
-       int policy,
-           posix_priority,
-           rv;
-       struct sched_param param;
-       gboolean ok = mono_w32handle_lookup (handle, MONO_W32HANDLE_THREAD,
-                                 (gpointer *)&thread_handle);
-                                 
-       if (ok == FALSE) {
-               return ok;
-       }
-       
-       rv = pthread_getschedparam (thread_handle->id, &policy, &param);
-       if (rv) {
-               if (ESRCH == rv)
-                       g_warning ("pthread_getschedparam: error looking up thread id %x", (gsize)thread_handle->id);
-               return FALSE;
-       }
-       
-       posix_priority =  wapi_thread_priority_to_posix_priority (priority, policy);
-       if (0 > posix_priority)
-               return FALSE;
-               
-       param.sched_priority = posix_priority;
-       switch (pthread_setschedparam (thread_handle->id, policy, &param)) {
-               case 0:
-                       thread_handle->priority = priority;
-                       return TRUE;
-               case ESRCH:
-                       g_warning ("pthread_setschedprio: error looking up thread id %x", (gsize)thread_handle->id);
-                       break;
-               case ENOTSUP:
-                       g_warning ("%s: priority %d not supported", __func__, priority);
-                       break;
-               case EPERM:
-                       g_warning ("%s: permission denied", __func__);
-                       break;
-       }
-       
-       return FALSE;
-}
index 7d0c384d0c15ed40a622d0cef57e605d3af5a5ab..3384a3c06a0c6b0531b0f1ffffdb81b6e74c87db 100644 (file)
@@ -2562,7 +2562,7 @@ 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.
         */
-       tp.priority = 0;
+       tp.priority = MONO_THREAD_PRIORITY_NORMAL;
        tp.stack_size = 0;
        tp.creation_flags = CREATE_SUSPENDED;
        thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, &tp, &tid);
index f1d52f5607d7dc558a677f2bdc6c46590bcb6888..6b970ae9a24a22560c7b4a30dbc42864db735274 100644 (file)
@@ -482,7 +482,7 @@ transport_start_receive (void)
        if (!listen_fd)
                return;
 
-       tp.priority = 0;
+       tp.priority = MONO_THREAD_PRIORITY_NORMAL;
        tp.stack_size = 0;
        tp.creation_flags = 0;
        receiver_thread_handle = mono_threads_create_thread (receiver_thread, NULL, &tp, NULL);
index 8ecabdb0e0becc4aa7c2748ce5ea3ab85240d6d2..f9b1c5f229c17a2716db780fd99a7c54d3bc8434 100644 (file)
@@ -42,14 +42,6 @@ typedef enum {
        ThreadApartmentState_Unknown = 0x00000002
 } MonoThreadApartmentState;
 
-typedef enum {
-       ThreadPriority_Lowest = 0,
-       ThreadPriority_BelowNormal = 1,
-       ThreadPriority_Normal = 2,
-       ThreadPriority_AboveNormal = 3,
-       ThreadPriority_Highest = 4
-} MonoThreadPriority;
-
 #define SPECIAL_STATIC_NONE 0
 #define SPECIAL_STATIC_THREAD 1
 #define SPECIAL_STATIC_CONTEXT 2
index b2ca672135c81d1035b8269d123d1569117586a2..567e7b466b3f37e69922508bcebcc7fab2c9d4d5 100644 (file)
@@ -603,7 +603,7 @@ new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal)
        MonoThread *thread;
 
        thread = create_thread_object (domain);
-       thread->priority = THREAD_PRIORITY_NORMAL;
+       thread->priority = MONO_THREAD_PRIORITY_NORMAL;
 
        MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
@@ -956,6 +956,7 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
        mono_error_init (error);
 
        thread = create_thread_object (domain);
+       thread->priority = MONO_THREAD_PRIORITY_NORMAL;
 
        internal = create_internal_thread ();
 
@@ -1448,9 +1449,9 @@ ves_icall_System_Threading_Thread_GetPriority (MonoThread *this_obj)
 
        LOCK_THREAD (internal);
        if (internal->handle != NULL)
-               priority = GetThreadPriority (internal->handle) + 2;
+               priority = mono_thread_info_get_priority ((MonoThreadInfo*) internal->thread_info);
        else
-               priority = this_obj->priority + 2;
+               priority = this_obj->priority;
        UNLOCK_THREAD (internal);
        return priority;
 }
@@ -1468,9 +1469,9 @@ ves_icall_System_Threading_Thread_SetPriority (MonoThread *this_obj, int priorit
        MonoInternalThread *internal = this_obj->internal_thread;
 
        LOCK_THREAD (internal);
-       this_obj->priority = priority - 2;
+       this_obj->priority = priority;
        if (internal->handle != NULL)
-               SetThreadPriority (internal->handle, this_obj->priority);
+               mono_thread_info_set_priority ((MonoThreadInfo*) internal->thread_info, this_obj->priority);
        UNLOCK_THREAD (internal);
 }
 
index 5719f5f1207d158d57f30b258e1595631142d73d..2d821b32d745c27dd438dd9bd01771c2f4746493 100644 (file)
@@ -9804,7 +9804,7 @@ compile_methods (MonoAotCompile *acfg)
                        user_data [1] = acfg;
                        user_data [2] = frag;
                        
-                       tp.priority = 0;
+                       tp.priority = MONO_THREAD_PRIORITY_NORMAL;
                        tp.stack_size = 0;
                        tp.creation_flags = 0;
                        handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)compile_thread_main, user_data, &tp, NULL);
index c84da624146e3fa8d14c8ba5758fd49301595972..a814155b33ea5b1ae2aae30295e9ee005f53b818 100644 (file)
@@ -1629,7 +1629,7 @@ start_debugger_thread (void)
 {
        MonoThreadParm tp;
 
-       tp.priority = 0;
+       tp.priority = MONO_THREAD_PRIORITY_NORMAL;
        tp.stack_size = 0;
        tp.creation_flags = 0;
        debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, &tp, NULL);
index 51c85e0a79f3dc7be1b76ee39c5bcd5d9b184bfc..8c1c9430ff6dc9c2d42a756f2dac9f014e5f6641 100644 (file)
@@ -48,7 +48,7 @@ thread_handle_create (void)
 
        thread_data.id = pthread_self ();
        thread_data.owned_mutexes = g_ptr_array_new ();
-       thread_data.priority = THREAD_PRIORITY_NORMAL;
+       thread_data.priority = MONO_THREAD_PRIORITY_NORMAL;
 
        thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, (gpointer) &thread_data);
        if (thread_handle == INVALID_HANDLE_VALUE)
@@ -62,6 +62,38 @@ thread_handle_create (void)
        return thread_handle;
 }
 
+static int
+win32_priority_to_posix_priority (MonoThreadPriority priority, int policy)
+{
+       g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
+       g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
+
+/* Necessary to get valid priority range */
+#ifdef _POSIX_PRIORITY_SCHEDULING
+       int max, min;
+
+       min = sched_get_priority_min (policy);
+       max = sched_get_priority_max (policy);
+
+       /* Partition priority range linearly (cross-multiply) */
+       if (max > 0 && min >= 0 && max > min)
+               return (int)((double) priority * (max - min) / (MONO_THREAD_PRIORITY_HIGHEST - MONO_THREAD_PRIORITY_LOWEST));
+#endif
+
+       switch (policy) {
+       case SCHED_FIFO:
+       case SCHED_RR:
+               return 50;
+#ifdef SCHED_BATCH
+       case SCHED_BATCH:
+#endif
+       case SCHED_OTHER:
+               return 0;
+       default:
+               return -1;
+       }
+}
+
 typedef struct {
        void *(*start_routine)(void*);
        void *arg;
@@ -96,7 +128,7 @@ inner_start_thread (void *arg)
        info->runtime_thread = TRUE;
        info->handle = handle;
 
-       wapi_init_thread_info_priority(handle, start_info->priority);
+       mono_threads_platform_set_priority (info, start_info->priority);
 
        if (flags & CREATE_SUSPENDED) {
                info->create_suspended = TRUE;
@@ -162,7 +194,7 @@ mono_threads_platform_create_thread (LPTHREAD_START_ROUTINE start_routine, gpoin
         */ 
        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);
+               sp.sched_priority = win32_priority_to_posix_priority (tp->priority, policy);
                res = pthread_attr_setschedparam (&attr, &sp);
        }
 
@@ -453,6 +485,67 @@ mono_threads_platform_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
        g_ptr_array_remove (thread_data->owned_mutexes, mutex_handle);
 }
 
+MonoThreadPriority
+mono_threads_platform_get_priority (MonoThreadInfo *info)
+{
+       MonoW32HandleThread *thread_data;
+
+       g_assert (info->handle);
+
+       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer *)&thread_data))
+               return MONO_THREAD_PRIORITY_NORMAL;
+
+       return thread_data->priority;
+}
+
+gboolean
+mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
+{
+       MonoW32HandleThread *thread_data;
+       int policy, posix_priority;
+       struct sched_param param;
+
+       g_assert (info->handle);
+
+       if (!mono_w32handle_lookup (info->handle, MONO_W32HANDLE_THREAD, (gpointer*) &thread_data))
+               return FALSE;
+
+       switch (pthread_getschedparam (thread_data->id, &policy, &param)) {
+       case 0:
+               break;
+       case ESRCH:
+               g_warning ("pthread_getschedparam: error looking up thread id %x", (gsize)thread_data->id);
+               return FALSE;
+       default:
+               return FALSE;
+       }
+
+       posix_priority =  win32_priority_to_posix_priority (priority, policy);
+       if (posix_priority < 0)
+               return FALSE;
+
+       param.sched_priority = posix_priority;
+       switch (pthread_setschedparam (thread_data->id, policy, &param)) {
+       case 0:
+               break;
+       case ESRCH:
+               g_warning ("%s: pthread_setschedprio: error looking up thread id %x", __func__, (gsize)thread_data->id);
+               return FALSE;
+       case ENOTSUP:
+               g_warning ("%s: priority %d not supported", __func__, priority);
+               return FALSE;
+       case EPERM:
+               g_warning ("%s: permission denied", __func__);
+               return FALSE;
+       default:
+               return FALSE;
+       }
+
+       thread_data->priority = priority;
+       return TRUE;
+
+}
+
 #endif /* defined(_POSIX_VERSION) || defined(__native_client__) */
 
 #if defined(USE_POSIX_BACKEND)
index 18c97b36125725d0a89630b27a75d8fddb285159..84321d653c286e599673fcd9e0c7cefa2dadf31f 100644 (file)
@@ -385,4 +385,16 @@ mono_threads_platform_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
        g_assert_not_reached ();
 }
 
+MonoThreadPriority
+mono_threads_platform_get_priority (MonoThreadInfo *info)
+{
+       return GetThreadPriority (info->handle) + 2;
+}
+
+gboolean
+mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
+{
+       return SetThreadPriority (info->handle, priority - 2);
+}
+
 #endif
index 1563efbffa135f875245a49e10b32e9b9eb52ec9..15b06b6d2b35f59f4a98b1d8b40d568c3c4121d1 100644 (file)
@@ -1595,3 +1595,15 @@ mono_thread_info_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
 {
        mono_threads_platform_disown_mutex (info, mutex_handle);
 }
+
+MonoThreadPriority
+mono_thread_info_get_priority (MonoThreadInfo *info)
+{
+       return mono_threads_platform_get_priority (info);
+}
+
+gboolean
+mono_thread_info_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
+{
+       return mono_threads_platform_set_priority (info, priority);
+}
index 2f17e2ea881ec6a5a95f1ff13cb0013bc9d1ac9d..375a808172c7fea92340a27b01d9c67294edc7f7 100644 (file)
@@ -289,6 +289,14 @@ typedef struct {
        guint32 stack_size;             
 } MonoThreadParm;
 
+typedef enum {
+       MONO_THREAD_PRIORITY_LOWEST       = 0,
+       MONO_THREAD_PRIORITY_BELOW_NORMAL = 1,
+       MONO_THREAD_PRIORITY_NORMAL       = 2,
+       MONO_THREAD_PRIORITY_ABOVE_NORMAL = 3,
+       MONO_THREAD_PRIORITY_HIGHEST      = 4,
+} MonoThreadPriority;
+
 static inline gboolean
 mono_threads_filter_tools_threads (THREAD_INFO_TYPE *info)
 {
@@ -534,6 +542,8 @@ void mono_threads_platform_set_exited (THREAD_INFO_TYPE *info);
 void mono_threads_platform_describe (THREAD_INFO_TYPE *info, GString *text);
 void mono_threads_platform_own_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 void mono_threads_platform_disown_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
+MonoThreadPriority mono_threads_platform_get_priority (THREAD_INFO_TYPE *info);
+gboolean mono_threads_platform_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
 
 void mono_threads_coop_begin_global_suspend (void);
 void mono_threads_coop_end_global_suspend (void);
@@ -660,4 +670,10 @@ mono_thread_info_own_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 void
 mono_thread_info_disown_mutex (THREAD_INFO_TYPE *info, gpointer mutex_handle);
 
+MonoThreadPriority
+mono_thread_info_get_priority (THREAD_INFO_TYPE *info);
+
+gboolean
+mono_thread_info_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
+
 #endif /* __MONO_THREADS_H__ */