diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-03-28 20:49:59 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2016-03-28 20:49:59 +0000 |
commit | f8a39e8f2370556ece725f86a978f083729f883f (patch) | |
tree | 15ad8598c8247512ff422c316f080c54fee2b642 /sys/kern | |
parent | a1f43f3fd80d2ba4f6c7087f8a04a4c9245ae420 (diff) |
Make sure that a thread that calls sched_yield(2) ends up on the run queue
behind all other threads in the process by temporarily lowering its priority.
This isn't optimal but it is the easiest way to guarantee that we make
progress when we're waiting on an other thread to release a lock. This
results in significant improvements for processes that suffer from lock
contention, most notably firefox. Unfortunately this means that sched_yield(2)
needs to grab the kernel lock again.
All the hard work was done by mpi@, based on observations of the behaviour
of the BFS scheduler diff by Michal Mazurek.
ok deraadt@
Diffstat (limited to 'sys/kern')
-rw-r--r-- | sys/kern/kern_synch.c | 21 | ||||
-rw-r--r-- | sys/kern/syscalls.master | 4 |
2 files changed, 21 insertions, 4 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index a57baf3a536..0760c759aab 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_synch.c,v 1.129 2016/03/09 13:38:50 mpi Exp $ */ +/* $openbsd: kern_synch.c,v 1.129 2016/03/09 13:38:50 mpi Exp $ */ /* $NetBSD: kern_synch.c,v 1.37 1996/04/22 01:38:37 christos Exp $ */ /* @@ -432,7 +432,24 @@ wakeup(const volatile void *chan) int sys_sched_yield(struct proc *p, void *v, register_t *retval) { - yield(); + struct proc *q; + int s; + + SCHED_LOCK(s); + /* + * If one of the threads of a multi-threaded process called + * sched_yield(2), drop its priority to ensure its siblings + * can make some progress. + */ + p->p_priority = p->p_usrpri; + TAILQ_FOREACH(q, &p->p_p->ps_threads, p_thr_link) + p->p_priority = max(p->p_priority, q->p_priority); + p->p_stat = SRUN; + setrunqueue(p); + p->p_ru.ru_nvcsw++; + mi_switch(); + SCHED_UNLOCK(s); + return (0); } diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index dcf18dcb8ac..7ad93da0c40 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.167 2016/03/21 22:41:29 bluhm Exp $ +; $OpenBSD: syscalls.master,v 1.168 2016/03/28 20:49:58 kettenis Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -514,7 +514,7 @@ #else 297 UNIMPL #endif -298 STD NOLOCK { int sys_sched_yield(void); } +298 STD { int sys_sched_yield(void); } 299 STD NOLOCK { pid_t sys_getthrid(void); } 300 OBSOL t32___thrsleep 301 STD { int sys___thrwakeup(const volatile void *ident, \ |