From mboxrd@z Thu Jan 1 00:00:00 1970 Date: Mon, 18 Sep 2000 20:54:50 +0100 From: forsyth@vitanuova.com To: 9fans@cs.psu.edu MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="upas-klqzhtkmaugpclxzlffyzbfplb" Message-Id: <20000918195957.6BA68199FF@mail> Subject: [9fans] re: spin/trace source for plan 9 scheduler Topicbox-Message-UUID: 0908a1b2-eac9-11e9-9e20-41e7f4b1d025 This is a multi-part message in MIME format. --upas-klqzhtkmaugpclxzlffyzbfplb Content-Disposition: inline Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit i tucked a copy away when it last appeared in the list. here it is. (i think this is the right one!) --upas-klqzhtkmaugpclxzlffyzbfplb Content-Disposition: attachment; filename=p9sched.p Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit #define N 3 /* number of processes */ chan cq = [N] of { byte }; /* a single console queue */ init { atomic { run sleeper(); run wakeupr(); run posterp() } } byte p_r; /* p->r, one for each process */ byte State; /* nonzero if sleeper is waiting */ byte p_notepending; byte R_lock; /* lock point, one for each console q */ byte R_p; /* r->p, nonzero if anyone is waiting */ #define Wakeme 1 /* scheduling state of sleeper, 0 or 1 */ #define Console 1 /* id of the console, there is just 1 */ #define lock(r) atomic { (R_lock == 0) -> R_lock = 1 } #define unlock(r) R_lock = 0 mtype = { mesg }; proctype sleeper() { /* sleep sequence * suppose we wait to receive * a mesg from the console cq */ again: p_r = Console; /* we're waiting */ lock(r); if /* if condition happened, never mind */ :: len(cq) > 0 -> /* it happened */ p_r = 0; /* not waiting anymore */ unlock(r); goto done /* never mind */ :: len(cq) == 0 /* now committed to call scheduler */ fi; if :: R_p -> /* a process already waits for R */ printf("double sleep %d\n", R_p); assert(0) :: !R_p -> /* all clear */ State = Wakeme; R_p = 1; /* register */ unlock(r) fi; if :: p_notepending == 0 -> (State == 0) /* sched() */ :: !p_notepending fi; if :: p_notepending != 0 -> p_notepending = 0; lock(r); if :: R_p == 1 -> R_p = 0 :: R_p != 1 fi; unlock(r) /* error(Eintr) */ fi; done: if :: len(cq) ->cq?mesg :: len(cq) == 0 fi; goto again } proctype posterp() { byte r; /* postnote * interrupt the waiting process */ again: p_notepending = 1; r = p_r; if :: r -> /* process i is waiting */ /* wake up; without calling wakeup itself */ lock(r); if :: p_r == 1 -> if :: R_p == 1 -> /* check we wont race */ if :: State == Wakeme -> R_p = 0; p_r = 0; State = 0 /* ready(p) */ :: State != Wakeme /* no asleep */ fi :: R_p != 1 /* else, skip */ fi :: p_r != 1 /* else, skip */ fi; unlock(r) :: !r fi; goto again } proctype wakeupr() { byte p; /* wakeup sequence * send mesg to cq */ again: cq!mesg; lock(r); p = R_p; if :: p -> R_p = 0; if :: State != Wakeme -> printf("panic wakeup state\n"); assert(0) :: State == Wakeme -> p_r = 0; State = 0 /* ready(p) */ fi :: !p fi; unlock(r); goto again } --upas-klqzhtkmaugpclxzlffyzbfplb--