| Index: nspr/pr/src/pthreads/ptthread.c
|
| ===================================================================
|
| --- nspr/pr/src/pthreads/ptthread.c (revision 233722)
|
| +++ nspr/pr/src/pthreads/ptthread.c (working copy)
|
| @@ -28,6 +28,14 @@
|
| #undef _POSIX_THREAD_PRIORITY_SCHEDULING
|
| #endif
|
|
|
| +#ifdef _PR_NICE_PRIORITY_SCHEDULING
|
| +#undef _POSIX_THREAD_PRIORITY_SCHEDULING
|
| +#include <sys/resource.h>
|
| +#ifndef HAVE_GETTID
|
| +#define gettid() (syscall(SYS_gettid))
|
| +#endif
|
| +#endif
|
| +
|
| /*
|
| * Record whether or not we have the privilege to set the scheduling
|
| * policy and priority of threads. 0 means that privilege is available.
|
| @@ -69,6 +77,21 @@
|
| 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
|
|
|
| /*
|
| @@ -98,6 +121,9 @@
|
| PRIntn rv;
|
| PRThread *thred = (PRThread*)arg;
|
| PRBool detached = (thred->state & PT_THREAD_DETACHED) ? PR_TRUE : PR_FALSE;
|
| +#ifdef _PR_NICE_PRIORITY_SCHEDULING
|
| + pid_t tid;
|
| +#endif
|
|
|
| /*
|
| * Both the parent thread and this new thread set thred->id.
|
| @@ -110,7 +136,29 @@
|
| */
|
| thred->id = pthread_self();
|
|
|
| +#ifdef _PR_NICE_PRIORITY_SCHEDULING
|
| /*
|
| + * We need to know the kernel thread ID of each thread in order to
|
| + * set its nice value hence we do it here instead of at creation time.
|
| + */
|
| + tid = gettid();
|
| + 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;
|
| + PR_NotifyAllCondVar(pt_book.cv);
|
| + PR_Unlock(pt_book.ml);
|
| +#endif
|
| +
|
| + /*
|
| ** DCE Threads can't detach during creation, so do it late.
|
| ** I would like to do it only here, but that doesn't seem
|
| ** to work.
|
| @@ -224,6 +272,9 @@
|
|
|
| thred->priority = PR_PRIORITY_NORMAL;
|
| thred->id = pthread_self();
|
| +#ifdef _PR_NICE_PRIORITY_SCHEDULING
|
| + thred->tid = gettid();
|
| +#endif
|
| rv = pthread_setspecific(pt_book.key, thred);
|
| PR_ASSERT(0 == rv);
|
|
|
| @@ -644,6 +695,30 @@
|
| if (rv != 0)
|
| rv = -1;
|
| }
|
| +#elif defined(_PR_NICE_PRIORITY_SCHEDULING)
|
| + PR_Lock(pt_book.ml);
|
| + while (thred->tid == 0)
|
| + PR_WaitCondVar(pt_book.cv, PR_INTERVAL_NO_TIMEOUT);
|
| + PR_Unlock(pt_book.ml);
|
| +
|
| + errno = 0;
|
| + rv = getpriority(PRIO_PROCESS, 0);
|
| +
|
| + /* 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: setpriority failed with error %d",
|
| + errno));
|
| + }
|
| + }
|
| #endif
|
|
|
| thred->priority = newPri;
|
| @@ -816,6 +891,8 @@
|
| int rv;
|
| PRThread *thred;
|
|
|
| + PR_ASSERT(priority == PR_PRIORITY_NORMAL);
|
| +
|
| #ifdef _PR_NEED_PTHREAD_INIT
|
| /*
|
| * On BSD/OS (3.1 and 4.0), the pthread subsystem is lazily
|
| @@ -862,6 +939,9 @@
|
| thred->startFunc = NULL;
|
| thred->priority = priority;
|
| thred->id = pthread_self();
|
| +#ifdef _PR_NICE_PRIORITY_SCHEDULING
|
| + thred->tid = gettid();
|
| +#endif
|
|
|
| thred->state = (PT_THREAD_DETACHED | PT_THREAD_PRIMORD);
|
| if (PR_SYSTEM_THREAD == type)
|
| @@ -902,7 +982,6 @@
|
| PR_ASSERT(0 == rv);
|
| rv = pthread_setspecific(pt_book.key, thred);
|
| PR_ASSERT(0 == rv);
|
| - PR_SetThreadPriority(thred, priority);
|
| } /* _PR_InitThreads */
|
|
|
| #ifdef __GNUC__
|
|
|