diff options
author | mdf <mdf@FreeBSD.org> | 2011-02-08 00:16:36 +0000 |
---|---|---|
committer | mdf <mdf@FreeBSD.org> | 2011-02-08 00:16:36 +0000 |
commit | 33ee365b5548dd6130fd6a2707e2169369e1fab6 (patch) | |
tree | 3696b04084e29d2a5b666d5e3854af878bb7879b /sys/kern/kern_synch.c | |
parent | 93acd8b57328416a75419b8798763cecaa1bbb29 (diff) | |
download | FreeBSD-src-33ee365b5548dd6130fd6a2707e2169369e1fab6.zip FreeBSD-src-33ee365b5548dd6130fd6a2707e2169369e1fab6.tar.gz |
Based on discussions on the svn-src mailing list, rework r218195:
- entirely eliminate some calls to uio_yeild() as being unnecessary,
such as in a sysctl handler.
- move should_yield() and maybe_yield() to kern_synch.c and move the
prototypes from sys/uio.h to sys/proc.h
- add a slightly more generic kern_yield() that can replace the
functionality of uio_yield().
- replace source uses of uio_yield() with the functional equivalent,
or in some cases do not change the thread priority when switching.
- fix a logic inversion bug in vlrureclaim(), pointed out by bde@.
- instead of using the per-cpu last switched ticks, use a per thread
variable for should_yield(). With PREEMPTION, the only reasonable
use of this is to determine if a lock has been held a long time and
relinquish it. Without PREEMPTION, this is essentially the same as
the per-cpu variable.
Diffstat (limited to 'sys/kern/kern_synch.c')
-rw-r--r-- | sys/kern/kern_synch.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/sys/kern/kern_synch.c b/sys/kern/kern_synch.c index ddc2186..a3e920d 100644 --- a/sys/kern/kern_synch.c +++ b/sys/kern/kern_synch.c @@ -413,9 +413,10 @@ mi_switch(int flags, struct thread *newtd) */ if (kdb_active) kdb_switch(); - if (flags & SW_VOL) + if (flags & SW_VOL) { td->td_ru.ru_nvcsw++; - else + td->td_swvoltick = ticks; + } else td->td_ru.ru_nivcsw++; #ifdef SCHED_STATS SCHED_STAT_INC(sched_switch_stats[flags & SW_TYPE_MASK]); @@ -538,6 +539,36 @@ synch_setup(void *dummy) loadav(NULL); } +int +should_yield(void) +{ + + return (ticks - curthread->td_swvoltick >= hogticks); +} + +void +maybe_yield(void) +{ + + if (should_yield()) + kern_yield(curthread->td_user_pri); +} + +void +kern_yield(int prio) +{ + struct thread *td; + + td = curthread; + DROP_GIANT(); + thread_lock(td); + if (prio >= 0) + sched_prio(td, prio); + mi_switch(SW_VOL | SWT_RELINQUISH, NULL); + thread_unlock(td); + PICKUP_GIANT(); +} + /* * General purpose yield system call. */ |