private InternalThread internal_thread;
object m_ThreadStartArg;
object pending_exception;
- int priority;
+ int priority = (int) ThreadPriority.Normal;
#endregion
#pragma warning restore 414
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_ */
#define WaitForMultipleObjects wapi_WaitForMultipleObjects
#define WaitForMultipleObjectsEx wapi_WaitForMultipleObjectsEx
#define WaitForInputIdle wapi_WaitForInputIdle
-#define GetThreadPriority wapi_GetThreadPriority
-#define SetThreadPriority wapi_SetThreadPriority
#endif /* __WAPI_REMAP_H__ */
_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, ¶m)) {
- 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, ¶m);
- 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, ¶m)) {
- 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;
-}
* 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);
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);
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
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);
mono_error_init (error);
thread = create_thread_object (domain);
+ thread->priority = MONO_THREAD_PRIORITY_NORMAL;
internal = create_internal_thread ();
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;
}
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);
}
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);
{
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);
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)
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;
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;
*/
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);
}
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, ¶m)) {
+ 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, ¶m)) {
+ 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)
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
{
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);
+}
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)
{
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);
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__ */