M port/auth.c => port/auth.c +2 -2
@@ 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;
}
M port/devproc.c => port/devproc.c +14 -8
@@ 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);
M port/portdat.h => port/portdat.h +7 -11
@@ 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 */
M port/portfns.h => port/portfns.h +1 -0
@@ 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);
M port/proc.c => port/proc.c +95 -124
@@ 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; i<conf.nproc; i++, pp++)
+ if(pp->wired && pp->pid)
+ nwired[pp->wired->machno]++;
+ bm = 0;
+ for(i=0; i<conf.nmach; i++)
+ if(nwired[i] < nwired[bm])
+ bm = i;
+ p->wired = 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; i<conf.nproc; i++) {
p = &procalloc.arena[i];
@@ 784,12 757,10 @@ procdump(void)
p->pid, 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);
M port/sysproc.c => port/sysproc.c +9 -6
@@ 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);