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--