Loading...
pthreads/pthread.c Libc-498 Libc-498.1.7
--- Libc/Libc-498/pthreads/pthread.c
+++ Libc/Libc-498.1.7/pthreads/pthread.c
@@ -217,6 +217,7 @@
 #define PTHREAD_START_POLICY_MASK 0xff
 #define PTHREAD_START_IMPORTANCE_MASK 0xffff
 
+static int pthread_setschedparam_internal(pthread_t, mach_port_t, int, const struct sched_param *);
 extern pthread_t __bsdthread_create(void (*func)(void *), void * func_arg, void * stack, pthread_t  thread, unsigned int flags);
 extern int __bsdthread_terminate(void * freeaddr, size_t freesize, mach_port_t kport, mach_port_t joinsem);
 
@@ -224,6 +225,8 @@
 static const vm_address_t PTHREAD_STACK_HINT = 0xF0000000;
 #elif defined(__i386__) || defined(__x86_64__)
 static const vm_address_t PTHREAD_STACK_HINT = 0xB0000000;
+#elif defined(__arm__)
+static const vm_address_t PTHREAD_STACK_HINT = 0x30000000;
 #else
 #error Need to define a stack address hint for this architecture
 #endif
@@ -890,7 +893,7 @@
 		t->death = SEMAPHORE_NULL;
 
 		if (kernel_thread != MACH_PORT_NULL)
-			pthread_setschedparam(t, t->policy, &t->param);
+			(void)pthread_setschedparam_internal(t, kernel_thread, t->policy, &t->param);
 	} while (0);
 	return (res);
 }
@@ -1650,8 +1653,9 @@
 /*
  * Set the scheduling policy and scheduling paramters for a thread.
  */
-int       
-pthread_setschedparam(pthread_t thread, 
+static int       
+pthread_setschedparam_internal(pthread_t thread, 
+		      mach_port_t  kport,
 		      int policy,
 		      const struct sched_param *param)
 {
@@ -1682,12 +1686,46 @@
 		default:
 			return (EINVAL);
 	}
-	ret = thread_policy(pthread_mach_thread_np(thread), policy, base, count, TRUE);
+	ret = thread_policy(kport, policy, base, count, TRUE);
 	if (ret != KERN_SUCCESS)
 			return (EINVAL);
-	thread->policy = policy;
-	thread->param = *param;
 	return (0);
+}
+
+int       
+pthread_setschedparam(pthread_t t, 
+		      int policy,
+		      const struct sched_param *param)
+{
+	mach_port_t kport = MACH_PORT_NULL;
+	int error;
+	int bypass = 1;
+
+	if (t != pthread_self() && t != &_thread ) { //since the main thread will not get de-allocated from underneath us
+		bypass = 0;
+		if (_pthread_lookup_thread(t, &kport, 0) != 0)
+			return(ESRCH);
+	} else
+		kport = t->kernel_thread;
+
+	error = pthread_setschedparam_internal(t, kport, policy, param);
+	if (error == 0) {
+		if (bypass == 0) {
+			/* ensure the thread is still valid */
+			LOCK(_pthread_list_lock);
+			if ((error = _pthread_find_thread(t)) != 0) {
+				UNLOCK(_pthread_list_lock);
+				return(error);
+			}
+			t->policy = policy;
+			t->param = *param;
+			UNLOCK(_pthread_list_lock);
+		}  else {
+			t->policy = policy;
+			t->param = *param;
+		}
+	}
+	return(error);
 }
 
 /*
@@ -3097,7 +3135,6 @@
 					}
 					return(0);
 				} else {
-					workqueue_list_unlock();
 					return(EBUSY);
 				}
 		}