From b0f3ee385e17e220fd6599867abcc828b0b28e25 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 16 Mar 2003 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2003-03-16 --- port/devproc.c | 5 +- port/proc.c | 131 +++++++++++++++++++++++++++++++++---------------- 2 files changed, 91 insertions(+), 45 deletions(-) diff --git a/port/devproc.c b/port/devproc.c index 7db88b29ad0c6f8057f68955f6cbac5b4aca8167..63f76603b33972aab63beadcd28136c7077c2e4d 100644 --- a/port/devproc.c +++ b/port/devproc.c @@ -1147,9 +1147,10 @@ procctlreq(Proc *p, char *va, int n) procpriority(p, pri, 0); break; case CMfixedpri: - if(!iseve()) + pri = atoi(cb->f[1]); + if(pri > PriNormal && !iseve()) error(Eperm); - procpriority(p, atoi(cb->f[1]), 1); + procpriority(p, pri, 1); break; case CMprivate: p->privatemem = 1; diff --git a/port/proc.c b/port/proc.c index 179c57edd81039b1bf4dfb258102e740a481ddbc..8a3ad8d3693147d07f82f119874cf9362b17d35a 100644 --- a/port/proc.c +++ b/port/proc.c @@ -260,17 +260,92 @@ ready(Proc *p) } /* - * yield the processor to any other runnable process + * remove a process from a scheduling queue (called splhi) + */ +static Proc* +dequeueproc(Schedq *rq, Proc *tp) +{ + Proc *l, *p; + + if(!canlock(runq)) + return nil; + + /* + * the queue may have changed before we locked runq, + * refind the target process. + */ + l = 0; + for(p = rq->head; p; p = p->rnext){ + if(p == tp) + break; + l = p; + } + + /* + * p->mach==0 only when process state is saved + */ + if(p == 0 || p->mach){ + unlock(runq); + return nil; + } + if(p->rnext == 0) + rq->tail = l; + if(l) + l->rnext = p->rnext; + else + rq->head = p->rnext; + if(rq->head == nil) + runvec &= ~(1<<(rq-runq)); + rq->n--; + nrdy--; + if(p->state != Ready) + print("dequeueproc %s %lud %s\n", p->text, p->pid, statename[p->state]); + + unlock(runq); + return p; +} + +/* + * yield the processor and drop our priority */ void yield(void) { if(anyready()){ - up->yield = 1; + up->quanta = 0; /* act like you used them all up */ sched(); } } +/* + * move up any process waiting more than its quanta + */ +static void +rebalance(void) +{ + Schedq *rq; + Proc *p; + + for(rq = runq; rq < &runq[Nrq]; rq++){ + p = rq->head; + if(p == nil) + continue; + if(p->mp != MACHP(m->machno)) + continue; + if(p->priority == p->basepri) + continue; + if(m->ticks - p->readytime < quanta[p->priority]/4) + continue; + splhi(); + p = dequeueproc(rq, p); + spllo(); + if(p == nil) + continue; + p->quanta = quanta[p->priority]; /* act like we used none */ + ready(p); + } +} + /* * pick a process to run */ @@ -278,7 +353,7 @@ Proc* runproc(void) { Schedq *rq; - Proc *p, *l, *tp; + Proc *p; ulong start, now; int i; @@ -287,6 +362,11 @@ runproc(void) if ((p = edf->edfrunproc()) != nil) return p; + if(m->fairness++ == 10){ + m->fairness = 0; + rebalance(); + } + loop: /* * find a process that last ran on this processor (affinity), @@ -301,13 +381,9 @@ loop: * */ for(rq = &runq[Nrq-1]; rq >= runq; rq--){ - for(tp = rq->head; tp; tp = tp->rnext){ - if(tp->yield){ - tp->yield = 0; - continue; - } - if(tp->mp == nil || tp->mp == MACHP(m->machno) - || (!tp->wired && i > 0)) + for(p = rq->head; p; p = p->rnext){ + if(p->mp == nil || p->mp == MACHP(m->machno) + || (!p->wired && i > 0)) goto found; } } @@ -323,40 +399,9 @@ loop: found: splhi(); - if(!canlock(runq)) - goto loop; - - /* - * the queue may have changed before we locked runq, - * refind the target process. - */ - l = 0; - for(p = rq->head; p; p = p->rnext){ - if(p == tp) - break; - l = p; - } - - /* - * p->mach==0 only when process state is saved - */ - if(p == 0 || p->mach){ - unlock(runq); + p = dequeueproc(rq, p); + if(p == nil) goto loop; - } - if(p->rnext == 0) - rq->tail = l; - if(l) - l->rnext = p->rnext; - else - rq->head = p->rnext; - if(rq->head == nil) - runvec &= ~(1<<(rq-runq)); - rq->n--; - nrdy--; - if(p->state != Ready) - print("runproc %s %lud %s\n", p->text, p->pid, statename[p->state]); - unlock(runq); p->state = Scheding; p->mp = MACHP(m->machno);