Ejemplo n.º 1
0
Archivo: proc.c Proyecto: npe9/harvey
/*
 * SMP performs better than AMP with few cores.
 * So, leave this here by now. We should probably
 * write a unified version of runproc good enough for
 * both SMP and AMP.
 */
static Proc*
smprunproc(void)
{
	Mach *m = machp();
	Schedq *rq;
	Proc *p;
	uint32_t start, now;
	int i;

	start = perfticks();
	run.preempts++;

loop:
	/*
	 *  find a process that last ran on this processor (affinity),
	 *  or one that hasn't moved in a while (load balancing).  Every
	 *  time around the loop affinity goes down.
	 */
	spllo();
	for(i = 0;; i++){
		/*
		 *  find the highest priority target process that this
		 *  processor can run given affinity constraints.
		 *
		 */
		for(rq = &run.runq[Nrq-1]; rq >= run.runq; rq--){
			for(p = rq->head; p; p = p->rnext){
				if(p->mp == nil || p->mp == sys->machptr[m->machno]
				|| (!p->wired && i > 0))
					goto found;
			}
		}

		/* waste time or halt the CPU */
		idlehands();
		/* remember how much time we're here */
		now = perfticks();
		m->perf.inidle += now-start;
		start = now;
	}

found:
	splhi();
	p = dequeueproc(&run, rq, p);
	if(p == nil)
		goto loop;

	p->state = Scheding;
	p->mp = sys->machptr[m->machno];

	if(edflock(p)){
		edfrun(p, rq == &run.runq[PriEdf]);	/* start deadline timer and do admin */
		edfunlock();
	}
	if(p->trace)
		proctrace(p, SRun, 0);
	return p;
}
Ejemplo n.º 2
0
Archivo: main.c Proyecto: 99years/plan9
/*
 *  exit kernel either on a panic or user request
 */
void
exit(int code)
{
	shutdown(code);
	splhi();
	if (m->machno == 0)
		archreboot();
	else {
		intrcpushutdown();
		stopcpu(m->machno);
		for (;;)
			idlehands();
	}
}
Ejemplo n.º 3
0
Archivo: proc.c Proyecto: npe9/harvey
Proc*
runproc(void)
{
	Mach *m = machp();
	Schedq *rq;
	Proc *p;
	uint32_t start, now;

	if(nosmp)
		return singlerunproc();

	//NIX modeset cannot work without halt every cpu at boot
	//if(sys->nmach <= AMPmincores)
	else
		return smprunproc();

	start = perfticks();
	run.preempts++;
	rq = nil;
	if(m->machno != 0){
		do{
			spllo();
			while(m->proc == nil)
				idlehands();
			now = perfticks();
			m->perf.inidle += now-start;
			start = now;
			splhi();
			p = m->proc;
		}while(p == nil);
		p->state = Scheding;
		p->mp = sys->machptr[m->machno];
	
		if(edflock(p)){
			edfrun(p, rq == &run.runq[PriEdf]);	/* start deadline timer and do admin */
			edfunlock();
		}
		if(p->trace)
			proctrace(p, SRun, 0);
		return p;
	}

	mach0sched();
	return nil;	/* not reached */
}
Ejemplo n.º 4
0
/*
 *  pick a process to run
 */
Proc*
runproc(void)
{
	Schedq *rq;
	Proc *p;
	ulong start, now;
	int i;
	void (*pt)(Proc*, int, vlong);

	start = perfticks();

	/* cooperative scheduling until the clock ticks */
	if((p = m->readied) != nil && p->mach == nil && p->state == Ready
	&& (p->wired == nil || p->wired == MACHP(m->machno))
	&& runq[Nrq-1].head == nil && runq[Nrq-2].head == nil){
		skipscheds++;
		rq = &runq[p->priority];
		goto found;
	}

	preempts++;

loop:
	/*
	 *  find a process that last ran on this processor (affinity),
	 *  or one that hasn't moved in a while (load balancing).  Every
	 *  time around the loop affinity goes down.
	 */
	spllo();
	for(i = 0;; i++){
		/*
		 *  find the highest priority target process that this
		 *  processor can run given affinity constraints.
		 *
		 */
		for(rq = &runq[Nrq-1]; rq >= runq; rq--){
			for(p = rq->head; p != nil; p = p->rnext){
				if(p->mp == nil || p->mp == MACHP(m->machno)
				|| (p->wired == nil && i > 0))
					goto found;
			}
		}

		/* waste time or halt the CPU */
		idlehands();

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

found:
	splhi();
	p = dequeueproc(rq, p);
	if(p == nil)
		goto loop;

	p->state = Scheding;
	p->mp = MACHP(m->machno);

	if(edflock(p)){
		edfrun(p, rq == &runq[PriEdf]);	/* start deadline timer and do admin */
		edfunlock();
	}
	pt = proctrace;
	if(pt != nil)
		pt(p, SRun, 0);
	return p;
}
Ejemplo n.º 5
0
Archivo: proc.c Proyecto: npe9/harvey
static Proc*
singlerunproc(void)
{
	Mach *m = machp();
	Schedq *rq;
	Proc *p;
	uint32_t start, now, skipscheds;
	int i;

	start = perfticks();

	/* cooperative scheduling until the clock ticks */
	if((p=m->readied) && p->mach==0 && p->state==Ready
	&& &run.runq[Nrq-1].head == nil && &run.runq[Nrq-2].head == nil){
		skipscheds++;
		rq = &run.runq[p->priority];
		if(0)hi("runproc going to found before loop...\n");
		goto found;
	}

	run.preempts++;

loop:
	/*
	 *  find a process that last ran on this processor (affinity),
	 *  or one that hasn't moved in a while (load balancing).  Every
	 *  time around the loop affinity goes down.
	 */
	spllo();
	for(i = 0;; i++){
		/*
		 *  find the highest priority target process that this
		 *  processor can run given affinity constraints.
		 *
		 */
		for(rq = &run.runq[Nrq-1]; rq >= run.runq; rq--){
			for(p = rq->head; p; p = p->rnext){
				if(p->mp == nil || p->mp == sys->machptr[m->machno]
				|| (!p->wired && i > 0))
				{
					if(0)hi("runproc going to found inside loop...\n");
					goto found;
				}
			}
		}

		/* waste time or halt the CPU */
		idlehands();

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

found:
	splhi();
	if(0)hi("runproc into found...\n");
	p = dequeueproc(&run, rq, p);
	if(p == nil)
	{
		if(0)hi("runproc p=nil :(\n");
			goto loop;
	}

	p->state = Scheding;
	if(0)hi("runproc, pm->mp = sys->machptr[m->machno]\n");
	p->mp = sys->machptr[m->machno];
	if(0){hi("runproc, sys->machptr[m->machno] = "); put64((uint64_t)p->mp); hi("\n");}

	if(edflock(p)){
		edfrun(p, rq == &run.runq[PriEdf]);	/* start deadline timer and do admin */
		edfunlock();
	}
	if(p->trace)
		proctrace(p, SRun, 0);
	/* avoiding warnings, this will be removed */
	USED(mach0sched); USED(smprunproc);
	if(0){hi("runproc, returning p ");
	put64((uint64_t)p);
	hi("\n");}

	
	return p;
}
Ejemplo n.º 6
0
Archivo: proc.c Proyecto: npe9/harvey
/*
 * Scheduling thread run as the main loop of cpu 0
 * Used in AMP sched.
 */
static void
mach0sched(void)
{
	Mach *m = machp();
	Schedq *rq;
	Proc *p;
	Mach *mp;
	uint32_t start, now;
	int n, i; //, j;

	assert(m->machno == 0);
	acmodeset(NIXKC);		/* we don't time share any more */
	n = 0;
	start = perfticks();
loop:

	/*
	 * find a ready process that we might run.
	 */
	spllo();
	for(rq = &run.runq[Nrq-1]; rq >= run.runq; rq--)
		for(p = rq->head; p; p = p->rnext){
			/*
			 * wired processes may only run when their core is available.
			 */
			if(p->wired != nil){
				if(p->wired->proc == nil)
					goto found;
				continue;
			}
			/*
			 * find a ready process that did run at an available core
			 * or one that has not moved for some time.
			 */
			if(p->mp == nil || p->mp->proc == nil || n>0){
				goto found;
			}
		}
	/* waste time or halt the CPU */
	idlehands();
	/* remember how much time we're here */
	now = perfticks();
	m->perf.inidle += now-start;
	start = now;
	n++;
	goto loop;

found:
	assert(m->machno == 0);
	splhi();
	/*
	 * find a core for this process, but honor wiring.
	 */
	mp = p->wired;
	if(mp != nil){
		if(mp->proc != nil)
			goto loop;
	}else{
		for(i = 0; i < MACHMAX; i++){
			/*j = pickcore(p->color, i);
			if((mp = sys->machptr[j]) != nil && mp->online && mp->nixtype == NIXTC){*/
			if((mp = sys->machptr[i]) != nil){ // && mp->online && mp->nixtype == NIXTC){
				if(mp != m && mp->proc == nil)
					break;
			}
		}
		if(i == MACHMAX){
			preemptfor(p);
			goto loop;
		}
	}

	p = dequeueproc(&run, rq, p);
	mp->proc = p;
	if(p != nil){
		p->state = Scheding;
		p->mp = mp;
	}

	n = 0;
	goto loop;
}
Ejemplo n.º 7
0
Archivo: proc.c Proyecto: 8l/inferno
Proc*
runproc(void)
{
	Proc *p, *l;
	Schedq *rq, *erq;

	erq = runq + Nrq - 1;
loop:
	splhi();
	for(rq = runq; rq->head == 0; rq++)
		if(rq >= erq) {
			idlehands();
			spllo();
			goto loop;
		}

	if(!canlock(runq))
		goto loop;
	/* choose first one we last ran on this processor at this level or hasn't moved recently */
	l = nil;
	for(p = rq->head; p != nil; p = p->rnext)
		if(p->mp == nil || p->mp == MACHP(m->machno) || p->movetime < MACHP(0)->ticks)
			break;
	if(p == nil)
		p = rq->head;
	/* p->mach==0 only when process state is saved */
	if(p == 0 || p->mach) {
		unlock(runq);
		goto loop;
	}
	if(p->rnext == nil)
		rq->tail = l;
	if(l)
		l->rnext = p->rnext;
	else
		rq->head = p->rnext;
	if(rq->head == nil){
		rq->tail = nil;
		occupied &= ~(1<<p->pri);
	}
	nrdy--;
	if(p->dbgstop){
		p->state = Stopped;
		unlock(runq);
		goto loop;
	}
	if(p->state != Ready)
		print("runproc %s %lud %s\n", p->text, p->pid, statename[p->state]);
	unlock(runq);
	p->state = Scheding;
	if(p->mp != MACHP(m->machno))
		p->movetime = MACHP(0)->ticks + HZ/10;
	p->mp = MACHP(m->machno);

/*
	if(edflock(p)){
		edfrun(p, rq == &runq[PriEdf]);	// start deadline timer and do admin
		edfunlock();
	}
*/
	return p;
}