~kris/9p

9hist

a91755ae5e6333bd3f690820f086645cd122ec7f — David du Colombier 23 years ago f03ce73
Plan 9 from Bell Labs 2003-02-28
6 files changed, 145 insertions(+), 152 deletions(-)

M pc/trap.c
M port/devproc.c
M port/portclock.c
M port/portdat.h
M port/portfns.h
M port/proc.c
M pc/trap.c => pc/trap.c +3 -18
@@ 310,26 310,11 @@ trap(Ureg* ureg)
		if(ctl->eoi)
			ctl->eoi(vno);

		/* 
		 *  preemptive scheduling.  to limit stack depth,
		 *  make sure process has a chance to return from
		 *  the current interrupt before being preempted a
		 *  second time.
		 */
		if(ctl->isintr && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
		if(up && up->state == Running)
		if(anyhigher())
		if(up->preempted == 0)
		if(!active.exiting){
			up->preempted = 1;
		if(ctl->isintr){
			intrtime(m, vno);
			sched();
			splhi();
			up->preempted = 0;
			return;
			if(up && ctl->irq != IrqTIMER && ctl->irq != IrqCLOCK)
				preempted();
		}
		if(ctl->isintr)
			intrtime(m, vno);
	}
	else if(vno <= nelem(excname) && user){
		spllo();

M port/devproc.c => port/devproc.c +9 -20
@@ 1094,7 1094,7 @@ void
procctlreq(Proc *p, char *va, int n)
{
	Segment *s;
	int i, npc;
	int npc, pri;
	Cmdbuf *cb;
	Cmdtab *ct;



@@ 1116,17 1116,6 @@ procctlreq(Proc *p, char *va, int n)
	case CMclosefiles:
		procctlclosefiles(p, 1, 0);
		break;
	case CMfixedpri:
		i = atoi(cb->f[1]);
		if(i < 0)
			i = 0;
		if(i >= Nrq)
			i = Nrq - 1;
		if(i > p->basepri && !iseve())
			error(Eperm);
		p->basepri = i;
		p->fixedpri = 1;
		break;
	case CMhang:
		p->hang = 1;
		break;


@@ 1152,15 1141,15 @@ procctlreq(Proc *p, char *va, int n)
		p->noswap = 1;
		break;
	case CMpri:
		i = atoi(cb->f[1]);
		if(i < 0)
			i = 0;
		if(i >= Nrq)
			i = Nrq - 1;
		if(i > p->basepri && !iseve())
		pri = atoi(cb->f[1]);
		if(pri > PriNormal && !iseve())
			error(Eperm);
		procpriority(p, pri, 0);
		break;
	case CMfixedpri:
		if(!iseve())
			error(Eperm);
		p->basepri = i;
		p->fixedpri = 0;
		procpriority(p, atoi(cb->f[1]), 1);
		break;
	case CMprivate:
		p->privatemem = 1;

M port/portclock.c => port/portclock.c +3 -21
@@ 95,8 95,6 @@ timerdel(Timer *dt)
void
hzclock(Ureg *ur)
{
	int callsched;

	m->ticks++;
	if(m->proc)
		m->proc->pc = ur->pc;


@@ 126,29 124,13 @@ hzclock(Ureg *ur)
	if(up == 0 || up->state != Running)
		return;

	if(up->fixedpri){
		/*  fixed priority processes are only preempted by
		 *  higher piority processes.
		 */
		if(anyhigher())
			callsched = 1;
	} else {
		/*  floating priority processes are are preempted
		 *  by all sorts of things.
		 */
		if(anyready() && !edf->isedf(up))
			callsched = 1;
	}
	if(callsched){
		sched();
		splhi();
	}

	/* user profiling clock */
	if(userureg(ur)) {
	if(userureg(ur)){
		(*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1);
		segclock(ur->pc);
	}

	hzsched();	/* in proc.c */
}

void

M port/portdat.h => port/portdat.h +2 -3
@@ 657,10 657,9 @@ struct Proc
	ulong	priority;	/* priority level */
	ulong	basepri;	/* base priority level */
	uchar	fixedpri;	/* priority level deson't change */
	ulong	rt;		/* # ticks used since last blocked */
	ulong	art;		/* avg # ticks used since last blocked */
	int	quanta;		/* quanta left */
	ulong	readytime;	/* time process came ready */
	ulong	movetime;	/* last time process switched processors */
	ulong	readytime;	/* time process went ready */
	int	preempted;	/* true if this process hasn't finished the interrupt
				 *  that last preempted it
				 */

M port/portfns.h => port/portfns.h +3 -0
@@ 119,6 119,7 @@ char*		getconfenv(void);
int		haswaitq(void*);
long		hostdomainwrite(char*, int);
long		hostownerwrite(char*, int);
void		hzsched(void);
void		iallocinit(void);
Block*		iallocb(int);
void		iallocsummary(void);


@@ 204,6 205,7 @@ void		panic(char*, ...);
Cmdbuf*		parsecmd(char *a, int n);
ulong		perfticks(void);
void		pexit(char*, int);
int		preempted(void);
void		printinit(void);
int		procindex(ulong);
void		pgrpcpy(Pgrp*, Pgrp*);


@@ 222,6 224,7 @@ void		procdump(void);
int		procfdprint(Chan*, int, int, char*, int);
void		procinit0(void);
void		procflushseg(Segment*);
void		procpriority(Proc*, int, int);
Proc*		proctab(int);
void		procwired(Proc*, int);
Pte*		ptealloc(void);

M port/proc.c => port/proc.c +125 -90
@@ 20,7 20,22 @@ static struct Procalloc
	Proc*	free;
} procalloc;

enum
{
	Q=(HZ/20)*4,
	DQ=((HZ-Q)/40)*2,
};

static Schedq	runq[Nrq];
static ulong	runvec;
static int	quanta[Nrq] =
{
	Q+19*DQ, Q+18*DQ, Q+17*DQ, Q+16*DQ,
	Q+15*DQ, Q+14*DQ, Q+13*DQ, Q+12*DQ,
	Q+11*DQ, Q+10*DQ, Q+ 9*DQ, Q+ 8*DQ,
	Q+ 7*DQ, Q+ 6*DQ, Q+ 5*DQ, Q+ 4*DQ,
	Q+ 3*DQ, Q+ 2*DQ, Q+ 1*DQ, Q+ 0*DQ,
};

extern Edfinterface	nulledf;



@@ 128,28 143,54 @@ sched(void)
int
anyready(void)
{
	return nrdy || edf->edfanyready();
	return runvec || edf->edfanyready();
}

int
anyhigher(void)
{
	Schedq *rq;
	return runvec & ~((1<<(up->priority+1))-1);
}

	if(nrdy == 0)
		return 0;
/*
 *  here once per clock tick to see if we should resched
 */
void
hzsched(void)
{
	/* another cycle, another quantum */
	up->quanta--;

	for(rq = &runq[Nrq-1]; rq > &runq[up->priority]; rq--)
		if(rq->head != nil)
			return 1;
	/* edf scheduler always gets first chance */
	if(edf->isedf(up))
		return;

	return 0;
	/* don't bother unless someone is elegible */
	if(anyhigher() || (!up->fixedpri && anyready())){
		sched();
		splhi();
	}
}

enum
/*
 *  here at the end of non-clock interrupts to see if we should preempt the
 *  current process.  Returns 1 if preempted, 0 otherwise.
 */
int
preempted(void)
{
	Squantum = 1,
};
	if(up && up->state == Running)
	if(up->preempted == 0)
	if(anyhigher())
	if(!active.exiting){
		up->preempted = 1;
		sched();
		splhi();
		up->preempted = 0;
		return 1;
	}
	return 0;
}

void
ready(Proc *p)


@@ 164,34 205,37 @@ ready(Proc *p)
		splx(s);
		return;
	}

	pri = p->priority;

	if(p->fixedpri){
		pri = p->basepri;
		p->quanta = HZ;
	} else if(p->state == Running){
		if(p->quanta <= 0){
			/* degrade priority of anyone that used their whole quanta */

			/* processes > PriNormal and those below don't mix */
			if(p->basepri > PriNormal){
				if(pri > PriNormal)
					pri--;
			} else {
				if(pri > 0)
					pri--;
			}
			p->quanta = quanta[pri];
		}
	} else {
		/* history counts */
		if(p->state == Running){
			p->rt++;
			pri = (p->art + p->rt)/2;
		} else {
			p->art = (p->art + p->rt + 2)/2;
			pri = (p->art + p->rt)/2;
			p->rt = 0;
		if(p->quanta > quanta[pri]/2){
			/* blocked before using half its quanta, go up */
			if(++pri > p->basepri)
				pri = p->basepri;
		}
		pri = p->basepri - (pri/Squantum);
		if(pri < 0)
			pri = 0;

		/* the only intersection between the classes is at PriNormal */
		if(pri < PriNormal && p->basepri > PriNormal)
			pri = PriNormal;

		/* stick at low priority any process waiting for a lock */
		if(p->lockwait)
			pri = PriLock;
		p->quanta = quanta[pri];
	}

	rq = &runq[pri];
	p->priority = pri;
	rq = &runq[p->priority];

	lock(runq);
	p->rnext = 0;
	if(rq->tail)


@@ 201,6 245,7 @@ ready(Proc *p)
	rq->tail = p;
	rq->n++;
	nrdy++;
	runvec |= 1<<pri;
	p->readytime = m->ticks;
	p->state = Ready;
	unlock(runq);


@@ 210,10 255,10 @@ ready(Proc *p)
Proc*
runproc(void)
{
	Schedq *rq, *xrq;
	Schedq *rq;
	Proc *p, *l;
	ulong rt;
	ulong start, now;
	int i;

	start = perfticks();



@@ 221,55 266,30 @@ runproc(void)
		return p;

loop:

	/*
	 *  find a process that last ran on this processor (affinity),
	 *  or one that hasn't moved in a while (load balancing).
	 *  or one that hasn't moved in a while (load balancing).  Every
	 *  time around the loop affinity goes down.
	 */
	spllo();
	for(;;){
		if((++(m->fairness) & 0x3) == 0){
			/*
			 *  once in a while, run process that's been waiting longest
			 *  regardless of movetime
			 */
			rt = 0xffffffff;
			xrq = nil;
			for(rq = runq; rq < &runq[Nrq]; rq++){
				p = rq->head;
				if(p == 0)
					continue;
				if(p->readytime < rt){
					xrq = rq;
					rt = p->readytime;
				}
			}
			if(xrq != nil){
				rq = xrq;
				p = rq->head;
				if(p != nil && p->wired == nil)
					p->movetime = 0;
				goto found;
			}
		} else {
			/*
			 *  get highest priority process that this
			 *  processor can run given affinity constraints
			 */
			for(rq = &runq[Nrq-1]; rq >= runq; rq--){
				p = rq->head;
				if(p == 0)
					continue;
				for(; p; p = p->rnext){
					if(p->mp == MACHP(m->machno)
					|| p->movetime < MACHP(0)->ticks)
						goto found;
				}
	for(i = 0;; i++){
		/*
		 *  get highest priority process that this
		 *  processor can run given affinity constraints
		 */
		for(rq = &runq[Nrq-1]; rq >= runq; rq--){
			p = rq->head;
			if(p == 0)
				continue;
			for(; p; p = p->rnext){
				if(p->mp == MACHP(m->machno) || (!p->wired && i > 0))
					goto found;
			}
		}

		/* remember how much time we're here */
		idlehands();

		/* remember how much time we're here */
		now = perfticks();
		m->perf.inidle += now-start;
		start = now;


@@ 282,7 302,7 @@ found:

	l = 0;
	for(p = rq->head; p; p = p->rnext){
		if(p->mp == MACHP(m->machno) || p->movetime <= MACHP(0)->ticks)
		if(p->mp == MACHP(m->machno) || (!p->wired && i > 0))
			break;
		l = p;
	}


@@ 300,6 320,8 @@ found:
		l->rnext = p->rnext;
	else
		rq->head = p->rnext;
	if(rq->head == nil)
		runvec &= ~(1<<(rq-runq));
	rq->n--;
	nrdy--;
	if(p->state != Ready)


@@ 307,8 329,6 @@ found:
	unlock(runq);

	p->state = Scheding;
	if(p->mp != MACHP(m->machno))
		p->movetime = MACHP(0)->ticks + HZ/10;
	p->mp = MACHP(m->machno);

	return p;


@@ 366,20 386,15 @@ newproc(void)
	p->kp = 0;
	p->procctl = 0;
	p->notepending = 0;
	p->mp = 0;
	p->movetime = 0;
	p->wired = 0;
	p->ureg = 0;
	p->privatemem = 0;
	p->noswap = 0;
	p->lockwait = nil;
	p->errstr = p->errbuf0;
	p->syserrstr = p->errbuf1;
	p->errbuf0[0] = '\0';
	p->errbuf1[0] = '\0';
	p->nlocks = 0;
	p->delaysched = 0;
	p->movetime = 0;
	kstrdup(&p->user, "*nouser");
	kstrdup(&p->text, "*notext");
	kstrdup(&p->args, "");


@@ 394,6 409,11 @@ newproc(void)
	if(p->kstack == 0)
		p->kstack = smalloc(KSTACK);

	/* sched params */
	p->mp = 0;
	p->wired = 0;
	procpriority(p, PriNormal, 0);

	p->task = nil;

	return p;


@@ 430,11 450,28 @@ procwired(Proc *p, int bm)
	}

	p->wired = MACHP(bm);
	p->movetime = 0xffffffff;
	p->mp = p->wired;
}

void
procpriority(Proc *p, int pri, int fixed)
{
	if(pri >= Nrq)
		pri = Nrq - 1;
	else if(pri < 0)
		pri = 0;
	p->basepri = pri;
	p->priority = pri;
	if(fixed){
		p->quanta = 0xfffff;
		p->fixedpri = 1;
	} else {
		p->quanta = quanta[pri];
		p->fixedpri = 0;
	}
}

void
procinit0(void)		/* bad planning - clashes with devproc.c */
{
	Proc *p;


@@ 967,9 1004,9 @@ dumpaproc(Proc *p)
	s = p->psstate;
	if(s == 0)
		s = statename[p->state];
	print("%3lud:%10s pc %8lux dbgpc %8lux  %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux\n",
	print("%3lud:%10s pc %8lux dbgpc %8lux  %8s (%s) ut %ld st %ld bss %lux qpc %lux nl %lud nd %lud lpc %lux pri %lud\n",
		p->pid, p->text, p->pc, dbgpc(p),  s, statename[p->state],
		p->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched, p->lastlock ? p->lastlock->pc : 0);
		p->time[0], p->time[1], bss, p->qpc, p->nlocks, p->delaysched, p->lastlock ? p->lastlock->pc : 0, p->priority);
}

void


@@ 1047,8 1084,7 @@ scheddump(void)
			continue;
		print("rq%ld:", rq-runq);
		for(p = rq->head; p; p = p->rnext)
			print(" %lud(%lud, %lud)", p->pid, m->ticks - p->readytime,
				MACHP(0)->ticks - p->movetime);
			print(" %lud(%lud)", p->pid, m->ticks - p->readytime);
		print("\n");
		delay(150);
	}


@@ 1083,8 1119,7 @@ kproc(char *name, void (*func)(void *), void *arg)
	p->ureg = 0;
	p->dbgreg = 0;

	p->basepri = PriKproc;
	p->priority = p->basepri;
	procpriority(p, PriKproc, 0);

	kprocchild(p, func, arg);