示例#1
0
文件: edf.c 项目: Requaos/harvey
static void
deadlineintr(Ureg* ureg, Timer *t)
{
	Proc *up = externup();
	/* Proc reached deadline */
	extern int panicking;
	Sched *sch;
	Proc *p;

	if(panicking || active.exiting)
		return;

	p = t->ta;
	now = ms();
	DPRINT("%lu deadlineintr %d[%s]\n", now, p->pid, statename[p->state]);
	/* If we're interrupting something other than the proc pointed to by t->a,
	 * we've already achieved recheduling, so we need not do anything
	 * Otherwise, we must cause a reschedule, but if we call sched()
	 * here directly, the timer interrupt routine will not finish its business
	 * Instead, we cause the resched to happen when the interrupted proc
	 * returns to user space
	 */
	if(p == up){
		if(up->trace)
			proctrace(up, SInts, 0);
		up->delaysched++;
		sch = procsched(up);
 		sch->delayedscheds++;
	}
}
示例#2
0
文件: edf.c 项目: Requaos/harvey
void
edfrun(Proc *p, int edfpri)
{
	Edf *e;
	int32_t tns;
	Sched *sch;

	e = p->edf;
	sch = procsched(p);
	/* Called with edflock held */
	if(edfpri){
		tns = e->d - now;
		if(tns <= 0 || e->S == 0){
			/* Deadline reached or resources exhausted,
			 * deschedule forthwith
			 */
			p->delaysched++;
			sch->delayedscheds++;
			e->s = now;
			return;
		}
		if(e->S < tns)
			tns = e->S;
		if(tns < 20)
			tns = 20;
		e->Timer.tns = 1000LL * tns;	/* µs to ns */
		if(e->Timer.tt == nil || e->Timer.tf != deadlineintr){
			DPRINT("%lu edfrun, deadline=%lu\n", now, tns);
		}else{
			DPRINT("v");
		}
		if(p->trace)
			proctrace(p, SInte, todget(nil) + e->Timer.tns);
		e->Timer.tmode = Trelative;
		e->Timer.tf = deadlineintr;
		e->Timer.ta = p;
		timeradd(&e->Timer);
	}else{
		DPRINT("<");
	}
	e->s = now;
}
示例#3
0
文件: proc.c 项目: npe9/harvey
int
canpage(Proc *p)
{
	int ok;
	Sched *sch;

	splhi();
	sch = procsched(p);
	lock(sch);
	/* Only reliable way to see if we are Running */
	if(p->mach == 0) {
		p->newtlb = 1;
		ok = 1;
	}
	else
		ok = 0;
	unlock(sch);
	spllo();

	return ok;
}
示例#4
0
文件: edf.c 项目: Requaos/harvey
int
edfready(Proc *p)
{
	Edf *e;
	Sched *sch;
	Schedq *rq;
	Proc *l, *pp;
	int32_t n;

	if((e = edflock(p)) == nil)
		return 0;

	if(p->state == Wakeme && p->r){
		iprint("edfready: wakeme\n");
	}
	if(e->d - now <= 0){
		/* past deadline, arrange for next release */
		if((e->flags & Sporadic) == 0){
			/*
			 * Non sporadic processes stay true to their period;
			 * calculate next release time.
			 */
			if((n = now - e->t) > 0){
				if(n < e->T)
					e->t += e->T;
				else
					e->t = now + e->T - (n % e->T);
			}
		}
		if(now - e->t < 0){
			/* Next release is in the future, schedule it */
			if(e->Timer.tt == nil || e->Timer.tf != releaseintr){
				n = e->t - now;
				if(n < 20)
					n = 20;
				e->Timer.tns = 1000LL * n;
				e->Timer.tmode = Trelative;
				e->Timer.tf = releaseintr;
				e->Timer.ta = p;
				timeradd(&e->Timer);
				DPRINT("%lu edfready %d[%s], release=%lu\n",
					now, p->pid, statename[p->state], e->t);
			}
			if(p->state == Running && (e->flags & (Yield|Yieldonblock)) == 0 && (e->flags & Extratime)){
				/* If we were running, we've overrun our CPU allocation
				 * or missed the deadline, continue running best-effort at low priority
				 * Otherwise we were blocked.  If we don't yield on block, we continue
				 * best effort
				 */
				DPRINT(">");
				p->basepri = PriExtra;
				p->fixedpri = 1;
				edfunlock();
				return 0;	/* Stick on runq[PriExtra] */
			}
			DPRINT("%lu edfready %d[%s] wait release at %lu\n",
				now, p->pid, statename[p->state], e->t);
			p->state = Waitrelease;
			edfunlock();
			return 1;	/* Make runnable later */
		}
		DPRINT("%lu edfready %d %s release now\n", now, p->pid, statename[p->state]);
		/* release now */
		release(p);
	}
	edfunlock();
	DPRINT("^");
	sch = procsched(p);
	rq = &sch->runq[PriEdf];
	/* insert in queue in earliest deadline order */
	lock(&sch->l);
	l = nil;
	for(pp = rq->head; pp; pp = pp->rnext){
		if(pp->edf->d > e->d)
			break;
		l = pp;
	}
	p->rnext = pp;
	if (l == nil)
		rq->head = p;
	else
		l->rnext = p;
	if(pp == nil)
		rq->tail = p;
	rq->n++;
	sch->nrdy++;
	sch->runvec |= 1 << PriEdf;
	p->priority = PriEdf;
	p->readytime = machp()->ticks;
	p->state = Ready;
	unlock(&sch->l);
	if(p->trace)
		proctrace(p, SReady, 0);
	return 1;
}
示例#5
0
文件: edf.c 项目: Requaos/harvey
static void
releaseintr(Ureg* ureg, Timer *t)
{
	Proc *up = externup();
	Proc *p;
	extern int panicking;
	Sched *sch;
	Schedq *rq;

	if(panicking || active.exiting)
		return;

	p = t->ta;
	if((edflock(p)) == nil)
		return;
	sch = procsched(p);
	DPRINT("%lu releaseintr %d[%s]\n", now, p->pid, statename[p->state]);
	switch(p->state){
	default:
		edfunlock();
		return;
	case Ready:
		/* remove proc from current runq */
		rq = &sch->runq[p->priority];
		if(dequeueproc(sch, rq, p) != p){
			DPRINT("releaseintr: can't find proc or lock race\n");
			release(p);	/* It'll start best effort */
			edfunlock();
			return;
		}
		p->state = Waitrelease;
		/* fall through */
	case Waitrelease:
		release(p);
		edfunlock();
		if(p->state == Wakeme){
			iprint("releaseintr: wakeme\n");
		}
		ready(p);
		if(up){
			up->delaysched++;
			sch->delayedscheds++;
		}
		return;
	case Running:
		release(p);
		edfrun(p, 1);
		break;
	case Wakeme:
		release(p);
		edfunlock();
		if(p->trend)
			wakeup(p->trend);
		p->trend = nil;
		if(up){
			up->delaysched++;
			sch->delayedscheds++;
		}
		return;
	}
	edfunlock();
}
示例#6
0
文件: proc.c 项目: npe9/harvey
/*
 *  ready(p) picks a new priority for a process and sticks it in the
 *  runq for that priority.
 */
void
ready(Proc *p)
{
	schedready(procsched(p), p, 0);
}