From d75610b71a40a3a99b6fc39ed02eb0b1afe8f101 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 2 Jan 1995 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1995-01-02 --- port/auth.c | 4 +- port/devproc.c | 22 +++-- port/portdat.h | 18 ++-- port/portfns.h | 1 + port/proc.c | 219 +++++++++++++++++++++---------------------------- port/sysproc.c | 15 ++-- 6 files changed, 128 insertions(+), 151 deletions(-) diff --git a/port/auth.c b/port/auth.c index 93896256cb3379907e7c57e70a980f446001d42d..b694cd8e35dd87294017de92401dc7d3f1a9ecd9 100644 --- a/port/auth.c +++ b/port/auth.c @@ -573,7 +573,7 @@ userwrite(char *a, int n) error(Eperm); memset(up->user, 0, NAMELEN); strcpy(up->user, "none"); - up->basepri = PriNormal; + up->nice = NiceNormal; return n; } @@ -598,7 +598,7 @@ hostownerwrite(char *a, int n) renameuser(eve, buf); memmove(eve, buf, NAMELEN); memmove(up->user, buf, NAMELEN); - up->basepri = PriNormal; + up->nice = NiceNormal; return n; } diff --git a/port/devproc.c b/port/devproc.c index cf4483b0f55b7d40ba948310622c2bae9b3703a1..2d08c19c23debf64dede4789d5354ff22279828d 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -396,8 +396,8 @@ procread(Chan *c, void *va, long n, ulong offset) l += s->top - s->base; } readnum(0, statbuf+j+NUMSIZE*6, NUMSIZE, l>>10, NUMSIZE); - readnum(0, statbuf+j+NUMSIZE*7, NUMSIZE, p->basepri, NUMSIZE); - readnum(0, statbuf+j+NUMSIZE*8, NUMSIZE, p->priority, NUMSIZE); + readnum(0, statbuf+j+NUMSIZE*7, NUMSIZE, p->nice, NUMSIZE); + readnum(0, statbuf+j+NUMSIZE*8, NUMSIZE, p->pri, NUMSIZE); memmove(a, statbuf+offset, n); return n; @@ -740,14 +740,20 @@ procctlreq(Proc *p, char *va, int n) if(strncmp(buf, "pri", 3) == 0){ if(n < 4) error(Ebadctl); - i = atoi(buf+4); + i = NiceNormal+atoi(buf+4); if(i < 0) i = 0; - if(i >= Nrq) - i = Nrq - 1; - if(i < p->basepri && !iseve()) - error(Eperm); - p->basepri = i; + if(i >= NiceMax) + i = NiceMax - 1; + p->nice = i; + } + else + if(strncmp(buf, "wired", 5) == 0){ + if(n < 6) + error(Ebadctl); + i = atoi(buf+6); + if(i) + procwired(p); } else error(Ebadctl); diff --git a/port/portdat.h b/port/portdat.h index 518de559a863001135a12ff69563e99231045424..13a0297394c127dbe34cb154179f7f596f1caf6d 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -501,10 +501,10 @@ enum NERR = 15, NNOTE = 5, - Nrq = 20, /* number of scheduler priority levels */ - PriNormal = 10, /* base priority for normal processes */ - PriKproc = 13, /* base priority for kernel processes */ - PriRoot = 13, /* base priority for root processes */ + NiceMax = 10, /* max nice */ + NiceNormal = 5, /* base nice for normal processes */ + NiceKproc = NiceNormal-2, /* nice for kernel processes */ + NiceRoot = NiceNormal-2, /* nice for root processes */ }; struct Proc @@ -584,13 +584,9 @@ struct Proc Note lastnote; int (*notify)(void*, char*); - Mach *mp; /* machine this process last ran on */ - ulong priority; /* priority level */ - ulong basepri; /* base priority level */ - ulong rt; /* # ticks used since last blocked */ - ulong art; /* avg # ticks used since last blocked */ - ulong movetime; /* last time process switched processors */ - ulong readytime; /* time process went ready */ + Mach *wired; /* machine this process must run on */ + int pri; /* scheduling priority - low is high priority */ + int nice; /* time-passing algorithm - low is high priority */ void *ureg; /* User registers for notes */ void *dbgreg; /* User registers for devproc */ diff --git a/port/portfns.h b/port/portfns.h index 41a76c8f1124985536f82e5b7f5057a2738f4b2e..2ed9523edaeda8444be28b7cbc47cc32875154fa 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -174,6 +174,7 @@ void procctl(Proc*); void procdump(void); void procinit0(void); Proc* proctab(int); +void procwired(Proc*); void ptclone(Chan*, int, int); void ptclose(Pthash*); Pte* ptealloc(void); diff --git a/port/proc.c b/port/proc.c index d3ca0d6baeab6a3d78c158494fb975be5256ace3..17da34fc641a77bb4ff2b172f54db782b03e45bc 100644 --- a/port/proc.c +++ b/port/proc.c @@ -30,8 +30,7 @@ typedef struct } Schedq; int nrdy; -int lastreadied; -Schedq runq[Nrq]; +Schedq runq; char *statename[] = { /* BUG: generate automatically */ @@ -117,151 +116,101 @@ anyready(void) int anyhigher(void) { - int x; - x = lastreadied; - lastreadied = 0; - return nrdy && x >= up->priority; + return nrdy; } -enum -{ - Squantum = (HZ+Nrq-1)/Nrq, -}; - void ready(Proc *p) { - int s, pri; - Schedq *rq; + int s; s = splhi(); - /* history counts */ - if(p->state == Running){ - p->rt++; - pri = ((p->art + (p->rt<<1))>>2)/Squantum; - } else { - p->art = (p->art + (p->rt<<1))>>2; - p->rt = 0; - pri = p->art/Squantum; - } - pri = p->basepri - pri; - if(pri < 0) - pri = 0; - - /* the only intersection between the classes is at PriNormal */ - if(pri < PriNormal && p->basepri > PriNormal) - pri = PriNormal; - p->priority = pri; - rq = &runq[p->priority]; - - lock(runq); + lock(&runq); p->rnext = 0; - if(rq->tail) - rq->tail->rnext = p; + if(runq.tail) + runq.tail->rnext = p; else - rq->head = p; - rq->tail = p; - rq->n++; + runq.head = p; + runq.tail = p; + runq.n++; nrdy++; - p->readytime = m->ticks; p->state = Ready; - if(p->priority > lastreadied) - lastreadied = p->priority; - unlock(runq); + unlock(&runq); splx(s); } Proc* runproc(void) { - int i; - Schedq *rq; - Proc *p, *l; - static ulong lastfair; + Proc *p, *bp, *op; loop: - - /* - * find a process that last ran on this processor (affinity), - * or one that hasn't moved in a while (load balancing). - */ spllo(); - for(;;){ + + /* look for potential proc while not locked */ + for(p=runq.head; p; p=p->rnext) { /* - * Once a second we look for a long waiting process - * in the lowest priority queue to make sure nothing - * gets starved out by a malfunctioning high priority - * process. + * state is not saved */ - if(m->machno == 0 && m->ticks - lastfair > HZ){ - lastfair = m->ticks; - for(rq = runq; rq < &runq[Nrq]; rq++){ - p = rq->head; - if(p){ - i = m->ticks - p->readytime; - if(i > HZ){ - p->art = 0; - p->movetime = 0; - goto found; - } - break; - } - } - } - + if(p->mach) + continue; /* - * get highest priority process that this - * processor can run given affinity constraints + * wired to another machine */ - for(rq = &runq[Nrq-1]; rq >= runq; rq--){ - p = rq->head; - if(p == 0) - continue; - for(; p; p = p->rnext){ - if(p->mp == m || m->ticks - p->movetime > HZ/2) - goto found; - } - } + if(p->wired && p->wired != m) + continue; + break; } + if(p == 0) + goto loop; - -found: splhi(); - lock(runq); + lock(&runq); - l = 0; - for(p = rq->head; p; p = p->rnext){ - if(p->mp == m || m->ticks - p->movetime > HZ/2) - break; - l = p; + /* find best proc while locked */ + bp = 0; + for(p=runq.head; p; p=p->rnext) { + if(p->mach) + continue; + if(p->wired && p->wired != m) + continue; + if(bp == 0 || p->pri < bp->pri) + bp = p; } - - /* - * p->mach==0 only when process state is saved - */ - if(p == 0 || p->mach){ - unlock(runq); + if(bp == 0) { + unlock(&runq); goto loop; } - if(p->rnext == 0) - rq->tail = l; - if(l) - l->rnext = p->rnext; + +found: + /* unlink found proc from runq */ + op = 0; + for(p=runq.head; p; p=p->rnext) { + if(p == bp) + break; + op = p; + } + if(op == 0) + runq.head = bp->rnext; else - rq->head = p->rnext; - rq->n--; + op->rnext = bp->rnext; + if(bp == runq.tail) + runq.tail = op; + + /* clear next so that unlocked runq will not loop */ + bp->rnext = 0; + + runq.n--; nrdy--; - if(p->state != Ready) - print("runproc %s %d %s\n", p->text, p->pid, statename[p->state]); - unlock(runq); - p->state = Scheding; - if(p->mp != m) - p->movetime = m->ticks; - p->mp = m; - return p; + if(bp->state != Ready) + print("runproc %s %d %s\n", bp->text, bp->pid, statename[bp->state]); + unlock(&runq); + + bp->state = Scheding; + return bp; } int @@ -270,13 +219,13 @@ canpage(Proc *p) int ok = 0; splhi(); - lock(runq); + lock(&runq); /* Only reliable way to see if we are Running */ if(p->mach == 0) { p->newtlb = 1; ok = 1; } - unlock(runq); + unlock(&runq); spllo(); return ok; @@ -316,8 +265,9 @@ newproc(void) p->kp = 0; p->procctl = 0; p->notepending = 0; - p->mp = 0; - p->movetime = 0; + p->nice = NiceNormal; + p->pri = 0; + p->wired = 0; memset(p->seg, 0, sizeof p->seg); p->pid = incref(&pidalloc); p->noteid = incref(¬eidalloc); @@ -329,6 +279,30 @@ newproc(void) return p; } +/* + * wire this proc to a machine + */ +void +procwired(Proc *p) +{ + Proc *pp; + int i, bm; + char nwired[MAXMACH]; + + memset(nwired, 0, sizeof(nwired)); + p->wired = 0; + pp = proctab(0); + for(i=0; iwired && pp->pid) + nwired[pp->wired->machno]++; + bm = 0; + for(i=0; iwired = MACHP(bm); +print("pid %d wired to machine %d\n", p->pid, p->wired->machno); +} + void procinit0(void) /* bad planning - clashes with devproc.c */ { @@ -767,7 +741,6 @@ procdump(void) char *s; Proc *p; ulong bss; - Schedq *rq; for(i=0; ipid, p->text, p->pc, s, statename[p->state], p->time[0], p->time[1], bss); } - for(rq = &runq[Nrq-1]; rq >= runq; rq--){ - if(rq->head == 0) - continue; - print("rq%d:", rq-runq); - for(p = rq->head; p; p = p->rnext) - print(" %d(%d)", p->pid, m->ticks - p->readytime); + if(runq.head != 0) { + print("rq:"); + for(p = runq.head; p; p = p->rnext) + print(" %d(%d)", p->pid, p->pri); print("\n"); } print("nrdy %d\n", nrdy); @@ -822,8 +793,8 @@ kproc(char *name, void (*func)(void *), void *arg) p->ureg = 0; p->dbgreg = 0; - p->basepri = PriKproc; - p->priority = p->basepri; + p->nice = NiceKproc; + p->pri = 0; kprocchild(p, func, arg); diff --git a/port/sysproc.c b/port/sysproc.c index e8ca8e57754e311ac8d9498d13f7b7acd4edfb0a..324683f63cce89c38a4d4a93885aa5781d84c031 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -178,9 +178,10 @@ sysrfork(ulong *arg) * (i.e. has bad properties) and has to be discarded. */ flushmmu(); - p->priority = up->priority; - p->basepri = up->basepri; - p->mp = up->mp; + p->nice = up->nice; + p->pri = up->pri; + if(up->wired) + procwired(p); ready(p); return pid; } @@ -396,9 +397,11 @@ sysexec(ulong *arg) /* * '/' processes are higher priority (hack to make /ip more responsive). */ - if(devchar[tc->type] == L'/') - up->basepri = PriRoot; - up->priority = up->basepri; + up->nice = NiceNormal; + if(devchar[tc->type] == L'/') { + up->nice = NiceRoot; + up->pri = 0; + } poperror(); close(tc);