Skip site navigation (1)Skip section navigation (2)
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>