summaryrefslogtreecommitdiffstats
path: root/lib/libthr
diff options
context:
space:
mode:
authordavidxu <davidxu@FreeBSD.org>2006-07-13 22:45:19 +0000
committerdavidxu <davidxu@FreeBSD.org>2006-07-13 22:45:19 +0000
commit2b1dbc0acb716180145708fa4f5787322ac795e2 (patch)
tree38d9ff271ff8237cbfb86fa05d16da871f8e0dd2 /lib/libthr
parent27c2ca32122c31456d60bac89aae091ff18728b0 (diff)
downloadFreeBSD-src-2b1dbc0acb716180145708fa4f5787322ac795e2.zip
FreeBSD-src-2b1dbc0acb716180145708fa4f5787322ac795e2.tar.gz
Caching scheduling policy and priority in userland, a critical but baddly
written application is frequently changing thread priority for SCHED_OTHER policy.
Diffstat (limited to 'lib/libthr')
-rw-r--r--lib/libthr/thread/thr_create.c7
-rw-r--r--lib/libthr/thread/thr_getschedparam.c13
-rw-r--r--lib/libthr/thread/thr_init.c6
-rw-r--r--lib/libthr/thread/thr_setprio.c30
-rw-r--r--lib/libthr/thread/thr_setschedparam.c14
5 files changed, 50 insertions, 20 deletions
diff --git a/lib/libthr/thread/thr_create.c b/lib/libthr/thread/thr_create.c
index 49e9b45..f0d7cd5 100644
--- a/lib/libthr/thread/thr_create.c
+++ b/lib/libthr/thread/thr_create.c
@@ -79,10 +79,9 @@ _pthread_create(pthread_t * thread, const pthread_attr_t * attr,
new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
else
new_thread->attr.flags &= ~PTHREAD_SCOPE_SYSTEM;
- /*
- * scheduling policy and scheduling parameters will be
- * inherited in following code.
- */
+
+ new_thread->attr.prio = curthread->attr.prio;
+ new_thread->attr.sched_policy = curthread->attr.sched_policy;
}
if (_thr_scope_system > 0)
diff --git a/lib/libthr/thread/thr_getschedparam.c b/lib/libthr/thread/thr_getschedparam.c
index 9d581ed..c3233cd 100644
--- a/lib/libthr/thread/thr_getschedparam.c
+++ b/lib/libthr/thread/thr_getschedparam.c
@@ -57,20 +57,17 @@ _pthread_getschedparam(pthread_t pthread, int *policy,
* thread.
*/
THR_LOCK(curthread);
- ret = thr_getscheduler((pid_t)curthread->tid, policy, param,
- sizeof(param));
- if (ret == -1)
- ret = errno;
+ *policy = curthread->attr.sched_policy;
+ param->sched_priority = curthread->attr.prio;
THR_UNLOCK(curthread);
+ ret = 0;
}
/* Find the thread in the list of active threads. */
else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
== 0) {
THR_THREAD_LOCK(curthread, pthread);
- ret = thr_getscheduler(pthread->tid, policy, param,
- sizeof(param));
- if (ret == -1)
- ret = errno;
+ *policy = pthread->attr.sched_policy;
+ param->sched_priority = pthread->attr.prio;
THR_THREAD_UNLOCK(curthread, pthread);
_thr_ref_delete(curthread, pthread);
}
diff --git a/lib/libthr/thread/thr_init.c b/lib/libthr/thread/thr_init.c
index 99bcea3..490c1b7 100644
--- a/lib/libthr/thread/thr_init.c
+++ b/lib/libthr/thread/thr_init.c
@@ -362,6 +362,8 @@ _libpthread_init(struct pthread *curthread)
static void
init_main_thread(struct pthread *thread)
{
+ struct sched_param sched_param;
+
/* Setup the thread attributes. */
thr_self(&thread->tid);
thread->attr = _pthread_attr_default;
@@ -407,6 +409,10 @@ init_main_thread(struct pthread *thread)
thread->state = PS_RUNNING;
+ thr_getscheduler(thread->tid, &thread->attr.sched_policy,
+ &sched_param, sizeof(sched_param));
+ thread->attr.prio = sched_param.sched_priority;
+
/* Others cleared to zero by thr_alloc() */
}
diff --git a/lib/libthr/thread/thr_setprio.c b/lib/libthr/thread/thr_setprio.c
index 03ac39c..78769d1 100644
--- a/lib/libthr/thread/thr_setprio.c
+++ b/lib/libthr/thread/thr_setprio.c
@@ -50,20 +50,34 @@ _pthread_setprio(pthread_t pthread, int prio)
param.sched_priority = prio;
if (pthread == curthread) {
THR_LOCK(curthread);
- ret = thr_setschedparam(curthread->tid, &param, sizeof(param));
- if (ret == -1)
- ret = errno;
- else
+ if (curthread->attr.sched_policy == SCHED_OTHER ||
+ curthread->attr.prio == prio) {
curthread->attr.prio = prio;
+ ret = 0;
+ } else {
+ ret = thr_setschedparam(curthread->tid,
+ &param, sizeof(param));
+ if (ret == -1)
+ ret = errno;
+ else
+ curthread->attr.prio = prio;
+ }
THR_UNLOCK(curthread);
} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
== 0) {
THR_THREAD_LOCK(curthread, pthread);
- ret = thr_setschedparam(pthread->tid, &param, sizeof(param));
- if (ret == -1)
- ret = errno;
- else
+ if (pthread->attr.sched_policy == SCHED_OTHER ||
+ pthread->attr.prio == prio) {
pthread->attr.prio = prio;
+ ret = 0;
+ } else {
+ ret = thr_setschedparam(pthread->tid, &param,
+ sizeof(param));
+ if (ret == -1)
+ ret = errno;
+ else
+ pthread->attr.prio = prio;
+ }
THR_THREAD_UNLOCK(curthread, pthread);
_thr_ref_delete(curthread, pthread);
}
diff --git a/lib/libthr/thread/thr_setschedparam.c b/lib/libthr/thread/thr_setschedparam.c
index 5e2d2bf..d766e37 100644
--- a/lib/libthr/thread/thr_setschedparam.c
+++ b/lib/libthr/thread/thr_setschedparam.c
@@ -55,6 +55,13 @@ _pthread_setschedparam(pthread_t pthread, int policy,
if (pthread == curthread) {
THR_LOCK(curthread);
+ if (curthread->attr.sched_policy == policy &&
+ (policy == SCHED_OTHER ||
+ curthread->attr.prio == param->sched_priority)) {
+ pthread->attr.prio = param->sched_priority;
+ THR_UNLOCK(curthread);
+ return (0);
+ }
ret = thr_setscheduler(curthread->tid, policy, param,
sizeof(param));
if (ret == -1)
@@ -67,6 +74,13 @@ _pthread_setschedparam(pthread_t pthread, int policy,
} else if ((ret = _thr_ref_add(curthread, pthread, /*include dead*/0))
== 0) {
THR_THREAD_LOCK(curthread, pthread);
+ if (pthread->attr.sched_policy == policy &&
+ (policy == SCHED_OTHER ||
+ pthread->attr.prio == param->sched_priority)) {
+ pthread->attr.prio = param->sched_priority;
+ THR_THREAD_UNLOCK(curthread, pthread);
+ return (0);
+ }
ret = thr_setscheduler(pthread->tid, policy, param,
sizeof(param));
if (ret == -1)
OpenPOWER on IntegriCloud