plan 9 kernel history: overview | file list | diff list

2002/0316/port/edf.c (diff list | history)

2002/0315/sys/src/9/port/edf.c:5,112002/0316/sys/src/9/port/edf.c:5,11 (short | long | prev | next)
2002/0315    
#include	"dat.h" 
#include	"fns.h" 
#include	"../port/error.h" 
#include	"../port/devsched.h" 
2002/0316    
#include	"../port/devrealtime.h" 
2002/0315    
#include	"../port/edf.h" 
 
/* debugging */ 
2002/0315/sys/src/9/port/edf.c:68,742002/0316/sys/src/9/port/edf.c:68,74
2002/0315    
/* Running/Preempted EDF tasks, head running, one stack per processor */ 
Taskq		edfstack[MAXMACH]; 
 
void (*devsched)(Task*, Ticks, int); 
2002/0316    
void (*devrt)(Task*, Ticks, int); 
2002/0315    
 
static void		edf_intr(Ureg*, Cycintr*); 
static void		edf_resched(Task *t); 
2002/0315/sys/src/9/port/edf.c:115,1302002/0316/sys/src/9/port/edf.c:115,130
2002/0315    
{ 
	Taskq *q; 
 
	DENTER("%.*sedfpush, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edfpush, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	q = edfstack + m->machno; 
	assert(t->runq.n || (up && up->task == t)); 
	if (q->head){ 
		assert(q->head->state == EdfRunning); 
		q->head->state = EdfPreempted; 
		if(devsched) devsched(q->head, now, SPreempt); 
2002/0316    
		if(devrt) devrt(q->head, now, SPreempt); 
2002/0315    
	} 
	t->rnext = q->head; 
	if(devsched) devsched(t, now, SRun); 
2002/0316    
	if(devrt) devrt(t, now, SRun); 
2002/0315    
	q->head = t; 
	DLEAVE; 
} 
2002/0315/sys/src/9/port/edf.c:135,1412002/0316/sys/src/9/port/edf.c:135,141
2002/0315    
	Task *t; 
	Taskq *q; 
 
	DENTER("%.*sedfpop\n", ind, tabs); 
2002/0316    
	DENTER("%.*s%d edfpop\n", ind, tabs, m->machno); 
2002/0315    
	q = edfstack + m->machno; 
	if (t = q->head){ 
		assert(t->state == EdfRunning); 
2002/0315/sys/src/9/port/edf.c:144,1502002/0316/sys/src/9/port/edf.c:144,150
2002/0315    
		if (q->head){ 
			assert(q->head->state == EdfPreempted); 
			q->head->state = EdfRunning; 
			if(devsched) devsched(q->head, now, SRun); 
2002/0316    
			if(devrt) devrt(q->head, now, SRun); 
2002/0315    
		} 
	} 
	DLEAVE; 
2002/0315/sys/src/9/port/edf.c:157,1632002/0316/sys/src/9/port/edf.c:157,163
2002/0315    
	Task *tt, **ttp; 
 
	ilock(q); 
	DENTER("%.*sedfenqueue, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edfenqueue, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	t->rnext = nil; 
	if (q->head == nil) { 
		q->head = t; 
2002/0315/sys/src/9/port/edf.c:188,1942002/0316/sys/src/9/port/edf.c:188,194
2002/0315    
{ 
	Task *t; 
 
	DENTER("%.*sedfdequeue\n", ind, tabs); 
2002/0316    
	DENTER("%.*s%d edfdequeue\n", ind, tabs, m->machno); 
2002/0315    
	ilock(q); 
	if (t = q->head){ 
		q->head = t->rnext; 
2002/0315/sys/src/9/port/edf.c:205,2112002/0316/sys/src/9/port/edf.c:205,211
2002/0315    
	Task **tp; 
 
	ilock(q); 
	DENTER("%.*sedfqremove, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edfqremove, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	for (tp = &q->head; *tp; tp = &(*tp)->rnext){ 
		if (*tp == t){ 
			*tp = t->rnext; 
2002/0315/sys/src/9/port/edf.c:226,2322002/0316/sys/src/9/port/edf.c:226,232
2002/0315    
	/* The current proc has blocked */ 
	ilock(&edflock); 
	t = p->task; 
	DENTER("%.*sedf_block, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_block, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
 
	assert(t); 
	assert(t->state == EdfRunning); 
2002/0315/sys/src/9/port/edf.c:239,2452002/0316/sys/src/9/port/edf.c:239,245
2002/0315    
	pt = edfpop(); 
	assert(pt == t); 
	t->state = EdfBlocked; 
	if(devsched) devsched(t, now, SBlock); 
2002/0316    
	if(devrt) devrt(t, now, SBlock); 
2002/0315    
	DLEAVE; 
	iunlock(&edflock); 
} 
2002/0315/sys/src/9/port/edf.c:250,2562002/0316/sys/src/9/port/edf.c:250,256
2002/0315    
	Task *t, *nt; 
 
	/* Task has reached its deadline, lock must be held */ 
	DENTER("%.*sedfdeadline, %s, %d\n", ind, tabs, edf_statename[p->task->state], p->task->runq.n); 
2002/0316    
	DENTER("%.*s%d edfdeadline, %s, %d\n", ind, tabs, m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0315    
	SET(nt); 
	if (p){ 
		nt = p->task; 
2002/0315/sys/src/9/port/edf.c:260,2662002/0316/sys/src/9/port/edf.c:260,266
2002/0315    
	t = edfpop(); 
 
	if(p != nil && nt != t){ 
		DPRINT("%.*sedfdeadline, %s, %d\n", ind, tabs, edf_statename[p->task->state], p->task->runq.n); 
2002/0316    
		DPRINT("%.*s%d edfdeadline, %s, %d\n", ind, tabs, m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0315    
		iunlock(&edflock); 
		assert(0 && p == nil || nt == t); 
	} 
2002/0315/sys/src/9/port/edf.c:267,2732002/0316/sys/src/9/port/edf.c:267,273
2002/0315    
 
	t->d = now; 
	t->state = EdfDeadline; 
	if(devsched) devsched(t, now, why); 
2002/0316    
	if(devrt) devrt(t, now, why); 
2002/0315    
	edf_resched(t); 
	DLEAVE; 
} 
2002/0315/sys/src/9/port/edf.c:275,2812002/0316/sys/src/9/port/edf.c:275,281
2002/0315    
void 
edf_deadline(Proc *p) 
{ 
	DENTER("%.*sedf_deadline\n", ind, tabs); 
2002/0316    
	DENTER("%.*s%d edf_deadline\n", ind, tabs, m->machno); 
2002/0315    
	/* Task has reached its deadline */ 
	ilock(&edflock); 
	now = fastticks(nil); 
2002/0315/sys/src/9/port/edf.c:291,2962002/0316/sys/src/9/port/edf.c:291,309
2002/0315    
 
	if (t->state != EdfExpelled) 
		return "task state";	/* should never happen */ 
2002/0316    
 
	/* simple sanity checks */ 
	if (t->T == 0) 
		return "T not set"; 
	if (t->C == 0) 
		return "C not set"; 
	if (t->D > t->T) 
		return "D > T"; 
	if (t->D == 0)	/* if D is not set, set it to T */ 
		t->D = t->T; 
	if (t->C > t->D) 
		return "C > D"; 
 
2002/0315    
	qlock(&edfschedlock); 
	if (err = edf_testschedulability(t)){ 
		qunlock(&edfschedlock); 
2002/0315/sys/src/9/port/edf.c:297,3172002/0316/sys/src/9/port/edf.c:310,331
2002/0315    
		return err; 
	} 
	ilock(&edflock); 
	DENTER("%.*sedf_admit, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_admit, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	now = fastticks(nil); 
 
	t->state = EdfAdmitted; 
2002/0316    
	if(devrt) devrt(t, t->d, SAdmit); 
2002/0315    
	if (up->task == t){ 
		DPRINT("%.*sedf_admitting self\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_admitting self\n", ind, tabs, m->machno); 
2002/0315    
		/* Admitting self, fake reaching deadline */ 
		t->r = now; 
		t->t = now + t->T; 
		t->d = now + t->D; 
		if(devsched) devsched(t, t->d, SDeadline); 
2002/0316    
		if(devrt) devrt(t, t->d, SDeadline); 
2002/0315    
		t->S = t->C; 
		t->scheduled = now; 
		t->state = EdfRunning; 
		if(devsched) devsched(t, now, SRun); 
2002/0316    
		if(devrt) devrt(t, now, SRun); 
2002/0315    
		setΔ(); 
		assert(t->runq.n > 0 || (up && up->task == t)); 
		edfpush(t); 
2002/0315/sys/src/9/port/edf.c:342,3482002/0316/sys/src/9/port/edf.c:356,362
2002/0315    
 
	qlock(&edfschedlock); 
	ilock(&edflock); 
	DENTER("%.*sedf_expel, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_expel, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	now = fastticks(nil); 
	switch(t->state){ 
	case EdfUnused: 
2002/0315/sys/src/9/port/edf.c:378,3842002/0316/sys/src/9/port/edf.c:392,398
2002/0315    
		break; 
	} 
	t->state = EdfExpelled; 
	if(devsched) devsched(t, now, SExpel); 
2002/0316    
	if(devrt) devrt(t, now, SExpel); 
2002/0315    
	setΔ(); 
	DLEAVE; 
	iunlock(&edflock); 
2002/0315/sys/src/9/port/edf.c:432,4382002/0316/sys/src/9/port/edf.c:446,452
2002/0315    
	Ticks ticks; 
	Task *t; 
 
	DENTER("%.*sedf_setclock\n", ind, tabs); 
2002/0316    
	DENTER("%.*s%d edf_setclock\n", ind, tabs, m->machno); 
2002/0315    
	ticks = ~0ULL; 
	if ((t = qwaitrelease.head) && t->r < ticks) 
		ticks = t->r; 
2002/0315/sys/src/9/port/edf.c:447,4652002/0316/sys/src/9/port/edf.c:461,479
2002/0315    
		return; 
	} 
	if (schedpoint.when){ 
		DPRINT("%.*scycintrdel %T\n", ind, tabs, ticks2time(schedpoint.when)); 
2002/0316    
		DPRINT("%.*s%d cycintrdel %T\n", ind, tabs, m->machno, ticks2time(schedpoint.when)); 
2002/0315    
		cycintrdel(&schedpoint); 
		schedpoint.when = 0; 
	} 
	if (ticks <= now){ 
		DPRINT("%.*sedf_timer: %T too late\n", ind, tabs, ticks2time(now-ticks)); 
2002/0316    
		DPRINT("%.*s%d edf_timer: %T too late\n", ind, tabs, m->machno, ticks2time(now-ticks)); 
2002/0315    
		ticks = now; 
	} 
	if (ticks != ~0ULL) { 
		DPRINT("%.*sprogram timer in %T\n", ind, tabs, ticks2time(ticks-now)); 
2002/0316    
		DPRINT("%.*s%d program timer in %T\n", ind, tabs, m->machno, ticks2time(ticks-now)); 
2002/0315    
		schedpoint.when = ticks; 
		cycintradd(&schedpoint); 
		DPRINT("%.*scycintradd %T\n", ind, tabs, ticks2time(schedpoint.when-now)); 
2002/0316    
		DPRINT("%.*s%d cycintradd %T\n", ind, tabs, m->machno, ticks2time(schedpoint.when-now)); 
2002/0315    
	} 
	clockintrsched(); 
	DLEAVE; 
2002/0315/sys/src/9/port/edf.c:469,4752002/0316/sys/src/9/port/edf.c:483,489
2002/0315    
edf_intr(Ureg *, Cycintr *cy) 
{ 
 
	DENTER("%.*sedf_intr\n", ind, tabs); 
2002/0316    
	DENTER("%.*s%d edf_intr\n", ind, tabs, m->machno); 
2002/0315    
	/* Timer interrupt 
	 * Timed events are: 
	 * 1. release a task (look in qwaitrelease) 
2002/0315/sys/src/9/port/edf.c:497,5092002/0316/sys/src/9/port/edf.c:511,523
2002/0315    
	Task *t; 
	Proc **pp; 
 
	DPRINT("%.*sedf_bury\n", ind, tabs); 
2002/0316    
	DPRINT("%.*s%d edf_bury\n", ind, tabs, m->machno); 
2002/0315    
	ilock(&edflock); 
	now = fastticks(nil); 
	if ((t = p->task) == nil){ 
		/* race condition? */ 
		iunlock(&edflock); 
		DPRINT("%.*sedf bury race, pid %lud\n", ind, tabs, p->pid); 
2002/0316    
		DPRINT("%.*s%d edf bury race, pid %lud\n", ind, tabs, m->machno, p->pid); 
2002/0315    
		return; 
	} 
	assert(edfstack[m->machno].head == t); 
2002/0315/sys/src/9/port/edf.c:520,5262002/0316/sys/src/9/port/edf.c:534,540
2002/0315    
		assert(t->runq.head == nil); 
		t->state = EdfIdle; 
	} 
	if(devsched) devsched(t, now, SBlock); 
2002/0316    
	if(devrt) devrt(t, now, SBlock); 
2002/0315    
	p->task = nil; 
	iunlock(&edflock); 
} 
2002/0315/sys/src/9/port/edf.c:531,5412002/0316/sys/src/9/port/edf.c:545,555
2002/0315    
	Task *t; 
 
	ilock(&edflock); 
	DENTER("%.*sedf_ready, %s, %d\n", ind, tabs, edf_statename[p->task->state], p->task->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_ready, %s, %d\n", ind, tabs, m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0315    
	if ((t = p->task) == nil){ 
		/* Must be a race */ 
		iunlock(&edflock); 
		DPRINT("%.*sedf ready race, pid %lud\n", ind, tabs, p->pid); 
2002/0316    
		DPRINT("%.*s%d edf ready race, pid %lud\n", ind, tabs, m->machno, p->pid); 
2002/0315    
		return; 
	} 
	p->rnext = 0; 
2002/0315/sys/src/9/port/edf.c:562,5732002/0316/sys/src/9/port/edf.c:576,587
2002/0315    
{ 
	Task *xt; 
 
	DENTER("%.*sedf_resched, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_resched, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	if (t->nproc == 0){ 
		/* No member processes */ 
		if (t->state > EdfIdle){ 
			t->state = EdfIdle; 
			if(devsched) devsched(t, now, SBlock); 
2002/0316    
			if(devrt) devrt(t, now, SBlock); 
2002/0315    
		} 
		DLEAVE; 
		return; 
2002/0315/sys/src/9/port/edf.c:574,5862002/0316/sys/src/9/port/edf.c:588,600
2002/0315    
	} 
	if (t->runq.n == 0 && (up == nil || up->task != t)){ 
		/* Member processes but none runnable */ 
		DPRINT("%.*sedf_resched, nothing runnable\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_resched, nothing runnable\n", ind, tabs, m->machno); 
2002/0315    
		if (t->state == EdfRunning) 
			edfpop(); 
 
		if (t->state >= EdfIdle && t->state != EdfBlocked){ 
			t->state = EdfBlocked; 
			if(devsched) devsched(t, now, SBlock); 
2002/0316    
			if(devrt) devrt(t, now, SBlock); 
2002/0315    
		} 
		DLEAVE; 
		return; 
2002/0315/sys/src/9/port/edf.c:590,5962002/0316/sys/src/9/port/edf.c:604,610
2002/0315    
 
	switch (t->state){ 
	case EdfUnused: 
		iprint("%.*sattempt to schedule unused task\n", ind, tabs); 
2002/0316    
		iprint("%.*s%d attempt to schedule unused task\n", ind, tabs, m->machno); 
2002/0315    
	case EdfExpelled: 
		DLEAVE; 
		return;	/* Not admitted */ 
2002/0315/sys/src/9/port/edf.c:619,6252002/0316/sys/src/9/port/edf.c:633,639
2002/0315    
	case EdfRunning: 
		if (t->r <= now){ 
			if (t->t < now){ 
				DPRINT("%.*sedf_resched, rerelease\n", ind, tabs); 
2002/0316    
				DPRINT("%.*s%d edf_resched, rerelease\n", ind, tabs, m->machno); 
2002/0315    
				/* Period passed, rerelease */ 
				t->r = now; 
				xt = edfpop(); 
2002/0315/sys/src/9/port/edf.c:630,6362002/0316/sys/src/9/port/edf.c:644,650
2002/0315    
			} 
			if (now < t->d){ 
				if (t->S > 0){ 
					DPRINT("%.*sedf_resched, resume\n", ind, tabs); 
2002/0316    
					DPRINT("%.*s%d edf_resched, resume\n", ind, tabs, m->machno); 
2002/0315    
					/* Running, not yet at deadline, leave it */ 
					DLEAVE; 
					return; 
2002/0315/sys/src/9/port/edf.c:640,6462002/0316/sys/src/9/port/edf.c:654,660
2002/0315    
			/* Released, but deadline is past, release at t->t */ 
			t->r = t->t; 
		} 
		DPRINT("%.*sedf_resched, schedule release\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_resched, schedule release\n", ind, tabs, m->machno); 
2002/0315    
		xt = edfpop(); 
		assert(xt == t); 
		edfenqueue(&qwaitrelease, t); 
2002/0315/sys/src/9/port/edf.c:651,6572002/0316/sys/src/9/port/edf.c:665,671
2002/0315    
	case EdfDeadline: 
		if (t->r <= now){ 
			if (t->t < now){ 
				DPRINT("%.*sedf_resched, rerelease\n", ind, tabs); 
2002/0316    
				DPRINT("%.*s%d edf_resched, rerelease\n", ind, tabs, m->machno); 
2002/0315    
				/* Period passed, rerelease */ 
				t->r = now; 
				edf_release(t); 
2002/0315/sys/src/9/port/edf.c:660,6702002/0316/sys/src/9/port/edf.c:674,684
2002/0315    
			} 
			if (now < t->d && (t->flags & Useblocking) == 0){ 
				if (t->S > 0){ 
					DPRINT("%.*sedf_resched, resume\n", ind, tabs); 
2002/0316    
					DPRINT("%.*s%d edf_resched, resume\n", ind, tabs, m->machno); 
2002/0315    
					/* Released, not yet at deadline, release (again) */ 
					t->state = EdfReleased; 
					edfenqueue(&qreleased, t); 
					if(devsched) devsched(t, now, SResume); 
2002/0316    
					if(devrt) devrt(t, now, SResume); 
2002/0315    
					DLEAVE; 
					return; 
				}else 
2002/0315/sys/src/9/port/edf.c:673,6792002/0316/sys/src/9/port/edf.c:687,693
2002/0315    
			/* Released, but deadline is past, release at t->t */ 
			t->r = t->t; 
		} 
		DPRINT("%.*sedf_resched, schedule release\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_resched, schedule release\n", ind, tabs, m->machno); 
2002/0315    
		edfenqueue(&qwaitrelease, t); 
		t->state = EdfAwaitrelease; 
		edf_setclock(); 
2002/0315/sys/src/9/port/edf.c:685,6992002/0316/sys/src/9/port/edf.c:699,713
2002/0315    
void 
edf_release(Task *t) 
{ 
	DENTER("%.*sedf_release, %s, %d\n", ind, tabs, edf_statename[t->state], t->runq.n); 
2002/0316    
	DENTER("%.*s%d edf_release, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	assert(t->runq.n > 0 || (up && up->task == t)); 
	t->t = t->r + t->T; 
	t->d = t->r + t->D; 
	if(devsched) devsched(t, t->d, SDeadline); 
2002/0316    
	if(devrt) devrt(t, t->d, SDeadline); 
2002/0315    
	t->S = t->C; 
	t->state = EdfReleased; 
	edfenqueue(&qreleased, t); 
	if(devsched) devsched(t, now, SRelease); 
2002/0316    
	if(devrt) devrt(t, now, SRelease); 
2002/0315    
	edf_setclock(); 
	DLEAVE; 
} 
2002/0315/sys/src/9/port/edf.c:727,7332002/0316/sys/src/9/port/edf.c:741,747
2002/0315    
	DENTER("edf_runproc %lud\n", nilcount); 
	if (nt && (t == nil || (nt->D < t->Δ && nt->d < t->d))){ 
		/* released task is better than current */ 
		DPRINT("%.*sedf_runproc: released\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_runproc: released\n", ind, tabs, m->machno); 
2002/0315    
		edfdequeue(&qreleased); 
		assert(nt->runq.n >= 1); 
		edfpush(nt); 
2002/0315/sys/src/9/port/edf.c:735,7412002/0316/sys/src/9/port/edf.c:749,755
2002/0315    
		t = nt; 
		t->scheduled = now; 
	}else{ 
		DPRINT("%.*sedf_runproc: current\n", ind, tabs); 
2002/0316    
		DPRINT("%.*s%d edf_runproc: current\n", ind, tabs, m->machno); 
2002/0315    
	} 
 
	assert (t->runq.n); 


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)