diff options
author | Gabriele Svelto <gsvelto@mozilla.com> | 2013-04-23 17:41:38 -0700 |
---|---|---|
committer | Gabriele Svelto <gsvelto@mozilla.com> | 2013-04-23 17:41:38 -0700 |
commit | 87bf56f154c417b546e81fbba0152b890d7d5e1f (patch) | |
tree | e032dadfde4ea72589dc4e3810c243858ebeba9a | |
parent | dd23261eec0b44abbd4a09f32b38ae2777d6376c (diff) | |
download | nspr-hg-87bf56f154c417b546e81fbba0152b890d7d5e1f.tar.gz |
Bug 861434: Adjust thread nice values relatively to the main thread's
nice value when using PR_SetThreadPriority() on Linux. r=wtc.
-rw-r--r-- | pr/src/pthreads/ptthread.c | 61 |
1 files changed, 41 insertions, 20 deletions
diff --git a/pr/src/pthreads/ptthread.c b/pr/src/pthreads/ptthread.c index abc27603..8a87c14f 100644 --- a/pr/src/pthreads/ptthread.c +++ b/pr/src/pthreads/ptthread.c @@ -62,9 +62,7 @@ static void _pt_thread_death(void *arg); static void _pt_thread_death_internal(void *arg, PRBool callDestructors); static void init_pthread_gc_support(void); -#if defined(_PR_DCETHREADS) || \ - defined(_POSIX_THREAD_PRIORITY_SCHEDULING) || \ - defined(_PR_NICE_PRIORITY_SCHEDULING) +#if defined(_PR_DCETHREADS) || defined(_POSIX_THREAD_PRIORITY_SCHEDULING) static PRIntn pt_PriorityMap(PRThreadPriority pri) { #ifdef NTO @@ -74,18 +72,26 @@ static PRIntn pt_PriorityMap(PRThreadPriority pri) * Jerry.Kirk@Nexwarecorp.com */ return 10; -#elif defined(_PR_NICE_PRIORITY_SCHEDULING) - /* This maps high priorities to low nice values: - * PR_PRIORITY_LOW 1 - * PR_PRIORITY_NORMAL 0 - * PR_PRIORITY_HIGH -1 - * PR_PRIORITY_URGENT -2 */ - return 1 - pri; #else return pt_book.minPrio + pri * (pt_book.maxPrio - pt_book.minPrio) / PR_PRIORITY_LAST; #endif } +#elif defined(_PR_NICE_PRIORITY_SCHEDULING) +/* + * This functions maps higher priorities to lower nice values relative to the + * nice value specified in the |nice| parameter. The corresponding relative + * adjustments are: + * + * PR_PRIORITY_LOW +1 + * PR_PRIORITY_NORMAL 0 + * PR_PRIORITY_HIGH -1 + * PR_PRIORITY_URGENT -2 + */ +static int pt_RelativePriority(int nice, PRThreadPriority pri) +{ + return nice + (1 - pri); +} #endif /* @@ -133,11 +139,18 @@ static void *_pt_root(void *arg) #ifdef _PR_NICE_PRIORITY_SCHEDULING /* * We need to know the kernel thread ID of each thread in order to - * set its priority hence we do it here instead of at creation time. + * set its nice value hence we do it here instead of at creation time. */ tid = gettid(); - - rv = setpriority(PRIO_PROCESS, tid, pt_PriorityMap(thred->priority)); + errno = 0; + rv = getpriority(PRIO_PROCESS, 0); + + /* If we cannot read the main thread's nice value don't try to change the + * new thread's nice value. */ + if (errno == 0) { + setpriority(PRIO_PROCESS, tid, + pt_RelativePriority(rv, thred->priority)); + } PR_Lock(pt_book.ml); thred->tid = tid; @@ -688,14 +701,22 @@ PR_IMPLEMENT(void) PR_SetThreadPriority(PRThread *thred, PRThreadPriority newPri PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT); PR_Unlock(pt_book.ml); - rv = setpriority(PRIO_PROCESS, thred->tid, pt_PriorityMap(newPri)); + errno = 0; + rv = getpriority(PRIO_PROCESS, 0); - if (rv == -1 && errno == EPERM) - { - /* We don't set pt_schedpriv to EPERM because adjusting the nice - * value might be permitted for certain ranges but not others */ - PR_LOG(_pr_thread_lm, PR_LOG_MIN, - ("PR_SetThreadPriority: no thread scheduling privilege")); + /* Do not proceed unless we know the main thread's nice value. */ + if (errno == 0) { + rv = setpriority(PRIO_PROCESS, thred->tid, + pt_RelativePriority(rv, newPri)); + + if (rv == -1) + { + /* We don't set pt_schedpriv to EPERM in case errno == EPERM + * because adjusting the nice value might be permitted for certain + * ranges but not for others. */ + PR_LOG(_pr_thread_lm, PR_LOG_MIN, + ("PR_SetThreadPriority: no thread scheduling privilege")); + } } #endif |