Date: Wed, 16 Nov 2011 17:48:05 +0000 (UTC) From: John Baldwin <jhb@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-8@freebsd.org Subject: svn commit: r227572 - in stable/8/sys: kern sys Message-ID: <201111161748.pAGHm5u8059853@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: jhb Date: Wed Nov 16 17:48:05 2011 New Revision: 227572 URL: http://svn.freebsd.org/changeset/base/227572 Log: Partially MFC 218195, 218424, and 221829: - Put the general logic for being a CPU hog into a new function should_yield(). - Encapsulate the common case of check-and-yield into a new function maybe_yield(). - Add kern_yield() as a more generic version of uio_yield() and reimplement uio_yield() in terms of kern_yield(). To preserve the ABI of struct thread, should_yield() in 8 continues to use PCPU_GET(switchticks) rather than the td_swvolticks added in 9. Also, existing users of uio_yield() are left unchanged. Instead, the routines are merely added for use by new code. Reviewed by: mdf Modified: stable/8/sys/kern/kern_subr.c stable/8/sys/kern/kern_synch.c stable/8/sys/sys/priority.h stable/8/sys/sys/proc.h Modified: stable/8/sys/kern/kern_subr.c ============================================================================== --- stable/8/sys/kern/kern_subr.c Wed Nov 16 17:41:31 2011 (r227571) +++ stable/8/sys/kern/kern_subr.c Wed Nov 16 17:48:05 2011 (r227572) @@ -455,15 +455,8 @@ phashinit(int elements, struct malloc_ty void uio_yield(void) { - struct thread *td; - td = curthread; - DROP_GIANT(); - thread_lock(td); - sched_prio(td, td->td_user_pri); - mi_switch(SW_INVOL | SWT_RELINQUISH, NULL); - thread_unlock(td); - PICKUP_GIANT(); + kern_yield(PRI_USER); } int Modified: stable/8/sys/kern/kern_synch.c ============================================================================== --- stable/8/sys/kern/kern_synch.c Wed Nov 16 17:41:31 2011 (r227571) +++ stable/8/sys/kern/kern_synch.c Wed Nov 16 17:48:05 2011 (r227572) @@ -536,6 +536,38 @@ synch_setup(void *dummy) loadav(NULL); } +int +should_yield(void) +{ + + return (ticks - PCPU_GET(switchticks) >= hogticks); +} + +void +maybe_yield(void) +{ + + if (should_yield()) + kern_yield(PRI_USER); +} + +void +kern_yield(int prio) +{ + struct thread *td; + + td = curthread; + DROP_GIANT(); + thread_lock(td); + if (prio == PRI_USER) + prio = td->td_user_pri; + if (prio >= 0) + sched_prio(td, prio); + mi_switch(SW_VOL | SWT_RELINQUISH, NULL); + thread_unlock(td); + PICKUP_GIANT(); +} + /* * General purpose yield system call. */ Modified: stable/8/sys/sys/priority.h ============================================================================== --- stable/8/sys/sys/priority.h Wed Nov 16 17:41:31 2011 (r227571) +++ stable/8/sys/sys/priority.h Wed Nov 16 17:48:05 2011 (r227572) @@ -117,6 +117,12 @@ #define PRI_MIN_IDLE (224) #define PRI_MAX_IDLE (PRI_MAX) +#ifdef _KERNEL +/* Other arguments for kern_yield(9). */ +#define PRI_USER -2 /* Change to current user priority. */ +#define PRI_UNCHANGED -1 /* Do not change priority. */ +#endif + struct priority { u_char pri_class; /* Scheduling class. */ u_char pri_level; /* Normal priority level. */ Modified: stable/8/sys/sys/proc.h ============================================================================== --- stable/8/sys/sys/proc.h Wed Nov 16 17:41:31 2011 (r227571) +++ stable/8/sys/sys/proc.h Wed Nov 16 17:48:05 2011 (r227572) @@ -817,9 +817,11 @@ void fork_exit(void (*)(void *, struct t struct trapframe *); void fork_return(struct thread *, struct trapframe *); int inferior(struct proc *p); +void kern_yield(int); void kick_proc0(void); int leavepgrp(struct proc *p); int maybe_preempt(struct thread *td); +void maybe_yield(void); void mi_switch(int flags, struct thread *newtd); int p_candebug(struct thread *td, struct proc *p); int p_cansee(struct thread *td, struct proc *p); @@ -842,6 +844,7 @@ void sess_hold(struct session *); void sess_release(struct session *); int setrunnable(struct thread *); void setsugid(struct proc *p); +int should_yield(void); int sigonstack(size_t sp); void sleepinit(void); void stopevent(struct proc *, u_int, u_int);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201111161748.pAGHm5u8059853>