Subject: Re: Moving scheduler semantics from cpu_switch() to kern_synch.c
To: None <tech-kern@NetBSD.org>
From: Daniel Sieger <dsieger@TechFak.Uni-Bielefeld.DE>
List: tech-kern
Date: 09/19/2006 00:23:32
--DBIVS5p969aUjpLe
Content-Type: multipart/mixed; boundary="uAKRQypu60I7Lcqm"
Content-Disposition: inline


--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi,
the attached two diffs move some of the scheduler semantics from
cpu_switch() to kern_synch.c. The function nextlwp() gets called from
mi_switch() if its second argument is NULL. It returns the next
runnable LWP from the highest priority runqueue or calls cpu_idle()
if all queues are empty. Seems to work fine on i386 (I'm sorry, but I
have no other archs to test it). Any suggestions/comments are more
than welcome.

Regards,
Daniel

--=20
Daniel Sieger  =20
Faculty of Technology
Bielefeld University

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="kern_synch.c.diff"
Content-Transfer-Encoding: quoted-printable

Index: kern_synch.c
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D
RCS file: /cvsroot/src/sys/kern/kern_synch.c,v
retrieving revision 1.167
diff -u -r1.167 kern_synch.c
--- kern_synch.c	7 Sep 2006 18:41:28 -0000	1.167
+++ kern_synch.c	18 Sep 2006 22:03:09 -0000
@@ -1008,12 +1008,11 @@
 	 */
 	uvmexp.swtch++;
 	if (newl =3D=3D NULL) {
-		retval =3D cpu_switch(l, NULL);
-	} else {
-		remrunqueue(newl);
-		cpu_switchto(l, newl);
-		retval =3D 0;
-	}
+	     newl =3D nextlwp();
+	     cpu_switchto(l, newl);
+	     retval =3D 0;
+	} else
+	     retval =3D cpu_switch(l, NULL);
=20
 	/*
 	 * If we are using h/w performance counters, restore context.
@@ -1422,5 +1421,45 @@
 #endif
 }
=20
+/*
+ * Find the next LWP from the first non-empty runqueue.
+ */
+struct lwp *
+nextlwp(void)
+{
+	struct prochd *rq;
+	struct lwp *l;
+	int whichq;
+=09
+	while (sched_whichqs =3D=3D 0)
+		cpu_idle();
+=09
+	whichq =3D ffs(sched_whichqs) - 1;
+	rq =3D &sched_qs[whichq];
+	l =3D rq->ph_link;
+	remrunqueue(l);
+	return l;
+}
+
+
+/*
+ * Waits until a LWP appears on one of the runqueues.
+ */
+void
+cpu_idle()
+{
+=09
+#if defined(LOCKDEBUG)
+	sched_unlock_idle();
+#endif
+	spl0();
+	while (sched_whichqs =3D=3D 0)
+		continue;
+	splhigh();
+#if defined(LOCKDEBUG)
+	sched_lock_idle();
+#endif
+}
+
 #undef RQMASK
 #endif /* !defined(__HAVE_MD_RUNQUEUE) */

--uAKRQypu60I7Lcqm
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="lwp.h.diff"

Index: lwp.h
===================================================================
RCS file: /cvsroot/src/sys/sys/lwp.h,v
retrieving revision 1.41
diff -u -r1.41 lwp.h
--- lwp.h	30 Jul 2006 21:58:11 -0000	1.41
+++ lwp.h	18 Sep 2006 22:02:26 -0000
@@ -165,14 +165,14 @@
 #ifndef remrunqueue
 void	remrunqueue (struct lwp *);
 #endif
+#ifndef nextlwp
+struct lwp *nextlwp(void);
+#endif
 void	resetpriority (struct lwp *);
 void	setrunnable (struct lwp *);
 #ifndef setrunqueue
 void	setrunqueue (struct lwp *);
 #endif
-#ifndef nextrunqueue
-struct lwp *nextrunqueue(void);
-#endif
 void	unsleep (struct lwp *);
 #ifndef cpu_switch
 int	cpu_switch (struct lwp *, struct lwp *);

--uAKRQypu60I7Lcqm--

--DBIVS5p969aUjpLe
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (SunOS)

iD8DBQFFDxxjJUKmeYzbnToRAipOAJ0c5iOPnXPftho7qGcqGUKmiJmkrgCfcgXR
VoBMoWRutLt0uXahBShSLCs=
=7TXn
-----END PGP SIGNATURE-----

--DBIVS5p969aUjpLe--