Browse Source

[threads] Import mono_thread_info_set_priority (#3543)

* [mono-threads] Remove MonoThreadParm.creation_flags

* [mono-threads] Remove MonoThreadParm.priority and set to MONO_THREAD_PRIORITY_NORMAL by default

* [threads] Wrap use of mono_thread_info_(get|set)_priority

* [threads] Store priority on MonoInternalThread

* [threads] Import mono_thread_info_set_priority

* [mono-threads] Remove MonoThreadParm
Ludovic Henry 9 years ago
parent
commit
bdaef1e697

+ 1 - 1
mcs/class/corlib/System.Threading/Thread.cs

@@ -90,6 +90,7 @@ namespace System.Threading {
 		private IntPtr flags;
 		private IntPtr thread_pinning_ref;
 		private IntPtr abort_protected_block_count;
+		private int priority = (int) ThreadPriority.Normal;
 		/* 
 		 * These fields are used to avoid having to increment corlib versions
 		 * when a new field is added to the unmanaged MonoThread structure.
@@ -122,7 +123,6 @@ namespace System.Threading {
 		private InternalThread internal_thread;
 		object m_ThreadStartArg;
 		object pending_exception;
-		int priority = (int) ThreadPriority.Normal;
 		#endregion
 #pragma warning restore 414
 

+ 1 - 5
mono/metadata/appdomain.c

@@ -2530,7 +2530,6 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
 	unload_data *thread_data;
 	MonoNativeThreadId tid;
 	MonoDomain *caller_domain = mono_domain_get ();
-	MonoThreadParm tp;
 
 	/* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, mono_native_thread_id_get ()); */
 
@@ -2587,10 +2586,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 = MONO_THREAD_PRIORITY_NORMAL;
-	tp.stack_size = 0;
-	tp.creation_flags = 0;
-	thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, &tp, &tid);
+	thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, 0, &tid);
 	if (thread_handle == NULL)
 		return;
 

+ 1 - 6
mono/metadata/attach.c

@@ -475,17 +475,12 @@ transport_send (int fd, guint8 *data, int len)
 static void
 transport_start_receive (void)
 {
-	MonoThreadParm tp;
-
 	transport_connect ();
 
 	if (!listen_fd)
 		return;
 
-	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);
+	receiver_thread_handle = mono_threads_create_thread (receiver_thread, NULL, 0, NULL);
 	g_assert (receiver_thread_handle);
 }
 

+ 1 - 1
mono/metadata/object-internals.h

@@ -380,6 +380,7 @@ struct _MonoInternalThread {
 	gsize    flags;
 	gpointer thread_pinning_ref;
 	gsize abort_protected_block_count;
+	gint32 priority;
 	/* 
 	 * These fields are used to avoid having to increment corlib versions
 	 * when a new field is added to this structure.
@@ -401,7 +402,6 @@ struct _MonoThread {
 	struct _MonoInternalThread *internal_thread;
 	MonoObject *start_obj;
 	MonoException *pending_exception;
-	gint32 priority;
 };
 
 typedef struct {

+ 8 - 0
mono/metadata/threads-types.h

@@ -42,6 +42,14 @@ typedef enum {
 	ThreadApartmentState_Unknown = 0x00000002
 } MonoThreadApartmentState;
 
+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;
+
 #define SPECIAL_STATIC_NONE 0
 #define SPECIAL_STATIC_THREAD 1
 #define SPECIAL_STATIC_CONTEXT 2

+ 86 - 14
mono/metadata/threads.c

@@ -549,7 +549,6 @@ new_thread_with_internal (MonoDomain *domain, MonoInternalThread *internal)
 	MonoThread *thread;
 
 	thread = create_thread_object (domain);
-	thread->priority = MONO_THREAD_PRIORITY_NORMAL;
 
 	MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
@@ -578,9 +577,84 @@ create_internal_thread (void)
 		MONO_GC_REGISTER_ROOT_PINNING (thread->thread_pinning_ref, MONO_ROOT_SOURCE_THREADING, "thread pinning reference");
 	}
 
+	thread->priority = MONO_THREAD_PRIORITY_NORMAL;
+
 	return thread;
 }
 
+static void
+mono_thread_internal_set_priority (MonoInternalThread *internal, MonoThreadPriority priority)
+{
+	g_assert (internal);
+	g_assert (internal->handle);
+
+	g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
+	g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
+	g_assert (MONO_THREAD_PRIORITY_LOWEST < MONO_THREAD_PRIORITY_HIGHEST);
+
+#ifdef HOST_WIN32
+	BOOL res;
+
+	res = SetThreadPriority (internal->handle, priority - 2);
+	if (!res)
+		g_error ("%s: SetThreadPriority failed, error %d", __func__, GetLastError ());
+#else /* HOST_WIN32 */
+	pthread_t tid;
+	int policy;
+	struct sched_param param;
+	gint res;
+
+	tid = thread_get_tid (internal);
+
+	res = pthread_getschedparam (tid, &policy, &param);
+	if (res != 0)
+		g_error ("%s: pthread_getschedparam failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+	int 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) {
+		double srange, drange, sposition, dposition;
+		srange = MONO_THREAD_PRIORITY_HIGHEST - MONO_THREAD_PRIORITY_LOWEST;
+		drange = max - min;
+		sposition = priority - MONO_THREAD_PRIORITY_LOWEST;
+		dposition = (sposition / srange) * drange;
+		param.sched_priority = (int)(dposition + 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_error ("%s: unknown policy %d", __func__, policy);
+		}
+	}
+
+	res = pthread_setschedparam (tid, policy, &param);
+	if (res != 0) {
+		if (res == EPERM) {
+			g_warning ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
+			return;
+		}
+		g_error ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", __func__, g_strerror (res), res);
+	}
+#endif /* HOST_WIN32 */
+}
+
 static void 
 mono_alloc_static_data (gpointer **static_data_ptr, guint32 offset, gboolean threadlocal);
 
@@ -707,6 +781,8 @@ static guint32 WINAPI start_wrapper_internal(StartInfo *start_info, gsize *stack
 		return 0;
 	}
 
+	mono_thread_internal_set_priority (internal, internal->priority);
+
 	tid = internal->tid;
 
 	start_delegate = start_info->start_delegate;
@@ -837,7 +913,6 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	StartInfo *start_info = NULL;
 	HANDLE thread_handle;
 	MonoNativeThreadId tid;
-	MonoThreadParm tp;
 	gboolean ret;
 
 	if (start_delegate)
@@ -882,11 +957,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
 	if (stack_size == 0)
 		stack_size = default_stacksize_for_thread (internal);
 
-	tp.priority = thread->priority;
-	tp.stack_size = stack_size;
-	tp.creation_flags = 0;
-
-	thread_handle = mono_threads_create_thread (start_wrapper, start_info, &tp, &tid);
+	thread_handle = mono_threads_create_thread (start_wrapper, start_info, stack_size, &tid);
 
 	if (thread_handle == NULL) {
 		/* The thread couldn't be created, so set an exception */
@@ -958,15 +1029,18 @@ 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 ();
 
 	MONO_OBJECT_SETREF (thread, internal_thread, internal);
 
+	LOCK_THREAD (internal);
+
 	res = create_thread (thread, internal, NULL, (MonoThreadStart) func, arg, threadpool_thread, stack_size, error);
 	return_val_if_nok (error, NULL);
 
+	UNLOCK_THREAD (internal);
+
 	return internal;
 }
 
@@ -1405,11 +1479,9 @@ ves_icall_System_Threading_Thread_GetPriority (MonoThread *this_obj)
 	MonoInternalThread *internal = this_obj->internal_thread;
 
 	LOCK_THREAD (internal);
-	if (internal->handle != NULL)
-		priority = mono_thread_info_get_priority ((MonoThreadInfo*) internal->thread_info);
-	else
-		priority = this_obj->priority;
+	priority = internal->priority;
 	UNLOCK_THREAD (internal);
+
 	return priority;
 }
 
@@ -1426,9 +1498,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;
+	internal->priority = priority;
 	if (internal->handle != NULL)
-		mono_thread_info_set_priority ((MonoThreadInfo*) internal->thread_info, this_obj->priority);
+		mono_thread_internal_set_priority (internal, priority);
 	UNLOCK_THREAD (internal);
 }
 

+ 1 - 5
mono/mini/aot-compiler.c

@@ -9775,7 +9775,6 @@ compile_methods (MonoAotCompile *acfg)
 		HANDLE handle;
 		gpointer *user_data;
 		MonoMethod **methods;
-		MonoThreadParm tp;
 
 		methods_len = acfg->methods->len;
 
@@ -9806,10 +9805,7 @@ compile_methods (MonoAotCompile *acfg)
 			user_data [1] = acfg;
 			user_data [2] = frag;
 			
-			tp.priority = MONO_THREAD_PRIORITY_NORMAL;
-			tp.stack_size = 0;
-			tp.creation_flags = 0;
-			handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, &tp, NULL);
+			handle = mono_threads_create_thread (compile_thread_main, (gpointer) user_data, 0, NULL);
 			g_ptr_array_add (threads, handle);
 		}
 		g_free (methods);

+ 1 - 6
mono/mini/debugger-agent.c

@@ -1627,12 +1627,7 @@ stop_debugger_thread (void)
 static void
 start_debugger_thread (void)
 {
-	MonoThreadParm tp;
-
-	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);
+	debugger_thread_handle = mono_threads_create_thread (debugger_thread, NULL, 0, NULL);
 	g_assert (debugger_thread_handle);
 }
 

+ 41 - 71
mono/utils/mono-threads-posix.c

@@ -46,7 +46,6 @@ mono_threads_platform_register (MonoThreadInfo *info)
 	gpointer thread_handle;
 
 	info->owned_mutexes = g_ptr_array_new ();
-	info->priority = MONO_THREAD_PRIORITY_NORMAL;
 
 	thread_handle = mono_w32handle_new (MONO_W32HANDLE_THREAD, NULL);
 	if (thread_handle == INVALID_HANDLE_VALUE)
@@ -61,6 +60,8 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_
 {
 	pthread_attr_t attr;
 	pthread_t thread;
+	int policy;
+	struct sched_param param;
 	gint res;
 
 	res = pthread_attr_init (&attr);
@@ -87,6 +88,45 @@ mono_threads_platform_create_thread (MonoThreadStart thread_fn, gpointer thread_
 	g_assert (!res);
 #endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
 
+	memset (&param, 0, sizeof (param));
+
+	res = pthread_attr_getschedpolicy (&attr, &policy);
+	if (res != 0)
+		g_error ("%s: pthread_attr_getschedpolicy failed, error: \"%s\" (%d)", g_strerror (res), res);
+
+#ifdef _POSIX_PRIORITY_SCHEDULING
+	int 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_error ("%s: unknown policy %d", __func__, policy);
+		}
+	}
+
+	res = pthread_attr_setschedparam (&attr, &param);
+	if (res != 0)
+		g_error ("%s: pthread_attr_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
+
 	/* Actually start the thread */
 	res = mono_gc_pthread_create (&thread, &attr, (gpointer (*)(gpointer)) thread_fn, thread_data);
 	if (res)
@@ -317,76 +357,6 @@ mono_threads_platform_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
 	g_ptr_array_remove (info->owned_mutexes, mutex_handle);
 }
 
-MonoThreadPriority
-mono_threads_platform_get_priority (MonoThreadInfo *info)
-{
-	return info->priority;
-}
-
-void
-mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
-{
-	int policy;
-	struct sched_param param;
-	pthread_t tid;
-	gint res;
-
-	g_assert (priority >= MONO_THREAD_PRIORITY_LOWEST);
-	g_assert (priority <= MONO_THREAD_PRIORITY_HIGHEST);
-	g_assert (MONO_THREAD_PRIORITY_LOWEST < MONO_THREAD_PRIORITY_HIGHEST);
-
-	tid = mono_thread_info_get_tid (info);
-
-	res = pthread_getschedparam (tid, &policy, &param);
-	if (res != 0)
-		g_error ("%s: pthread_getschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
-
-#ifdef _POSIX_PRIORITY_SCHEDULING
-	int 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) {
-		double srange, drange, sposition, dposition;
-		srange = MONO_THREAD_PRIORITY_HIGHEST - MONO_THREAD_PRIORITY_LOWEST;
-		drange = max - min;
-		sposition = priority - MONO_THREAD_PRIORITY_LOWEST;
-		dposition = (sposition / srange) * drange;
-		param.sched_priority = (int)(dposition + 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_error ("%s: unknown policy %d", __func__, policy);
-		}
-	}
-
-	res = pthread_setschedparam (tid, policy, &param);
-	if (res != 0) {
-		if (res == EPERM) {
-			g_warning ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
-			return;
-		}
-		g_error ("%s: pthread_setschedparam failed, error: \"%s\" (%d)", g_strerror (res), res);
-	}
-
-	info->priority = priority;
-}
-
 static const gchar* thread_typename (void)
 {
 	return "Thread";

+ 0 - 19
mono/utils/mono-threads-windows.c

@@ -335,25 +335,6 @@ mono_threads_platform_disown_mutex (MonoThreadInfo *info, gpointer mutex_handle)
 	g_assert_not_reached ();
 }
 
-MonoThreadPriority
-mono_threads_platform_get_priority (MonoThreadInfo *info)
-{
-	g_assert (info->handle);
-	return GetThreadPriority (info->handle) + 2;
-}
-
-void
-mono_threads_platform_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
-{
-	BOOL res;
-
-	g_assert (info->handle);
-
-	res = SetThreadPriority (info->handle, priority - 2);
-	if (!res)
-		g_error ("%s: SetThreadPriority failed, error %d", __func__, GetLastError ());
-}
-
 void
 mono_threads_platform_init (void)
 {

+ 2 - 20
mono/utils/mono-threads.c

@@ -1149,7 +1149,6 @@ inner_start_thread (gpointer data)
 	MonoThreadStart start_routine;
 	gpointer start_routine_arg;
 	guint32 start_routine_res;
-	gint32 priority;
 	gsize dummy;
 
 	thread_data = (CreateThreadData*) data;
@@ -1158,13 +1157,9 @@ inner_start_thread (gpointer data)
 	start_routine = thread_data->start_routine;
 	start_routine_arg = thread_data->start_routine_arg;
 
-	priority = thread_data->priority;
-
 	info = mono_thread_info_attach (&dummy);
 	info->runtime_thread = TRUE;
 
-	mono_threads_platform_set_priority (info, priority);
-
 	thread_data->handle = mono_thread_info_duplicate_handle (info);
 
 	mono_coop_sem_post (&thread_data->registered);
@@ -1192,7 +1187,7 @@ inner_start_thread (gpointer data)
  * Returns: a windows or io-layer handle for the thread.
  */
 HANDLE
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid)
+mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize stack_size, MonoNativeThreadId *out_tid)
 {
 	CreateThreadData *thread_data;
 	gint res;
@@ -1202,10 +1197,9 @@ mono_threads_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm
 	thread_data->ref = 2;
 	thread_data->start_routine = start;
 	thread_data->start_routine_arg = arg;
-	thread_data->priority = tp->priority;
 	mono_coop_sem_init (&thread_data->registered, 0);
 
-	res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) thread_data, tp->stack_size, out_tid);
+	res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) thread_data, stack_size, out_tid);
 	if (res != 0) {
 		/* ref is not going to be decremented in inner_start_thread */
 		InterlockedDecrement (&thread_data->ref);
@@ -1685,15 +1679,3 @@ 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);
-}
-
-void
-mono_thread_info_set_priority (MonoThreadInfo *info, MonoThreadPriority priority)
-{
-	mono_threads_platform_set_priority (info, priority);
-}

+ 1 - 27
mono/utils/mono-threads.h

@@ -245,7 +245,6 @@ typedef struct {
 #if defined(_POSIX_VERSION) || defined(__native_client__)
 	/* This is the data that was stored in the w32 handle */
 	GPtrArray *owned_mutexes;
-	gint32 priority;
 #endif
 } MonoThreadInfo;
 
@@ -285,23 +284,6 @@ typedef enum {
 
 typedef SuspendThreadResult (*MonoSuspendThreadCallback) (THREAD_INFO_TYPE *info, gpointer user_data);
 
-/*
- * Parameters to pass for thread creation
- */
-typedef struct {
-	int priority;
-	guint32 creation_flags;	
-	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)
 {
@@ -466,7 +448,7 @@ gboolean
 mono_thread_info_is_live (THREAD_INFO_TYPE *info);
 
 HANDLE
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, MonoThreadParm *tp, MonoNativeThreadId *out_tid);
+mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize stack_size, MonoNativeThreadId *out_tid);
 
 int
 mono_threads_get_max_stack_size (void);
@@ -549,8 +531,6 @@ 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);
-void mono_threads_platform_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
 gpointer mono_threads_platform_duplicate_handle (THREAD_INFO_TYPE *info);
 
 void mono_threads_coop_begin_global_suspend (void);
@@ -678,10 +658,4 @@ 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);
-
-void
-mono_thread_info_set_priority (THREAD_INFO_TYPE *info, MonoThreadPriority priority);
-
 #endif /* __MONO_THREADS_H__ */