~kris/9p

9hist

b0f3ee385e17e220fd6599867abcc828b0b28e25 — David du Colombier 23 years ago 3138c21
Plan 9 from Bell Labs 2003-03-16
2 files changed, 91 insertions(+), 45 deletions(-)

M port/devproc.c
M port/proc.c
M port/devproc.c => port/devproc.c +3 -2
@@ 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;

M port/proc.c => port/proc.c +88 -43
@@ 260,25 260,100 @@ 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
 */
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);