summaryrefslogtreecommitdiffstats
path: root/sys/kern/kern_synch.c
diff options
context:
space:
mode:
authormdf <mdf@FreeBSD.org>2011-02-08 00:16:36 +0000
committermdf <mdf@FreeBSD.org>2011-02-08 00:16:36 +0000
commit33ee365b5548dd6130fd6a2707e2169369e1fab6 (patch)
tree3696b04084e29d2a5b666d5e3854af878bb7879b /sys/kern/kern_synch.c
parent93acd8b57328416a75419b8798763cecaa1bbb29 (diff)
downloadFreeBSD-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.c35
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.
*/
OpenPOWER on IntegriCloud