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

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

2002/0321/sys/src/9/port/edf.c:10,202002/0322/sys/src/9/port/edf.c:10,16 (short | long | prev | next)
2002/0315    
 
/* debugging */ 
int			edfprint = 0; 
char			tabs[16] = "																"; 
int			ind; 
#define DPRINT	if(edfprint)iprint 
#define DENTER	ind++;if(edfprint)iprint 
#define DLEAVE	ind-- 
 
char *edf_statename[] = { 
	[EdfUnused] =		"Unused", 
2002/0321/sys/src/9/port/edf.c:115,1212002/0322/sys/src/9/port/edf.c:111,117
2002/0315    
{ 
	Taskq *q; 
 
2002/0316    
	DENTER("%.*s%d edfpush, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edfpush, %s, %d\n", 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){ 
2002/0321/sys/src/9/port/edf.c:126,1322002/0322/sys/src/9/port/edf.c:122,127
2002/0315    
	t->rnext = q->head; 
2002/0316    
	if(devrt) devrt(t, now, SRun); 
2002/0315    
	q->head = t; 
	DLEAVE; 
} 
 
static Task* 
2002/0321/sys/src/9/port/edf.c:135,1412002/0322/sys/src/9/port/edf.c:130,136
2002/0315    
	Task *t; 
	Taskq *q; 
 
2002/0316    
	DENTER("%.*s%d edfpop\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edfpop\n", m->machno); 
2002/0315    
	q = edfstack + m->machno; 
	if (t = q->head){ 
		assert(t->state == EdfRunning); 
2002/0321/sys/src/9/port/edf.c:147,1532002/0322/sys/src/9/port/edf.c:142,147
2002/0316    
			if(devrt) devrt(q->head, now, SRun); 
2002/0315    
		} 
	} 
	DLEAVE; 
	return t; 
} 
 
2002/0321/sys/src/9/port/edf.c:157,1672002/0322/sys/src/9/port/edf.c:151,160
2002/0315    
	Task *tt, **ttp; 
 
	ilock(q); 
2002/0316    
	DENTER("%.*s%d edfenqueue, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edfenqueue, %s, %d\n", m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	t->rnext = nil; 
	if (q->head == nil) { 
		q->head = t; 
		DLEAVE; 
		iunlock(q); 
		return t; 
	} 
2002/0321/sys/src/9/port/edf.c:178,1842002/0322/sys/src/9/port/edf.c:171,176
2002/0315    
		tt->rnext = t; 
	if (t != q->head) 
		t = nil; 
	DLEAVE; 
	iunlock(q); 
	return t; 
} 
2002/0321/sys/src/9/port/edf.c:188,1942002/0322/sys/src/9/port/edf.c:180,186
2002/0315    
{ 
	Task *t; 
 
2002/0316    
	DENTER("%.*s%d edfdequeue\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edfdequeue\n", m->machno); 
2002/0315    
	ilock(q); 
	if (t = q->head){ 
		q->head = t->rnext; 
2002/0321/sys/src/9/port/edf.c:195,2012002/0322/sys/src/9/port/edf.c:187,192
2002/0315    
		t->rnext = nil; 
	} 
	iunlock(q); 
	DLEAVE; 
	return t; 
} 
 
2002/0321/sys/src/9/port/edf.c:205,2202002/0322/sys/src/9/port/edf.c:196,209
2002/0315    
	Task **tp; 
 
	ilock(q); 
2002/0316    
	DENTER("%.*s%d edfqremove, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edfqremove, %s, %d\n", 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; 
			DLEAVE; 
			iunlock(q); 
			return; 
		} 
	} 
	DLEAVE; 
	iunlock(q); 
} 
 
2002/0321/sys/src/9/port/edf.c:232,2432002/0322/sys/src/9/port/edf.c:221,231
2002/0320    
		iunlock(&edflock); 
		return; 
	} 
2002/0316    
	DENTER("%.*s%d edf_block, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edf_block, %s, %d\n", m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
 
	if (t->runq.n){ 
		/* There's another runnable proc in the running task, leave task where it is */ 
		iunlock(&edflock); 
		DLEAVE; 
		return; 
	} 
	pt = edfpop(); 
2002/0321/sys/src/9/port/edf.c:244,2502002/0322/sys/src/9/port/edf.c:232,237
2002/0315    
	assert(pt == t); 
	t->state = EdfBlocked; 
2002/0316    
	if(devrt) devrt(t, now, SBlock); 
2002/0315    
	DLEAVE; 
	iunlock(&edflock); 
} 
 
2002/0321/sys/src/9/port/edf.c:254,2602002/0322/sys/src/9/port/edf.c:241,247
2002/0315    
	Task *t, *nt; 
 
	/* Task has reached its deadline, lock must be held */ 
2002/0316    
	DENTER("%.*s%d edfdeadline, %s, %d\n", ind, tabs, m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0322    
	DPRINT("%d edfdeadline, %s, %d\n", m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0315    
	SET(nt); 
	if (p){ 
		nt = p->task; 
2002/0321/sys/src/9/port/edf.c:273,2912002/0322/sys/src/9/port/edf.c:260,276
2002/0315    
	t->state = EdfDeadline; 
2002/0316    
	if(devrt) devrt(t, now, why); 
2002/0315    
	edf_resched(t); 
	DLEAVE; 
} 
 
void 
edf_deadline(Proc *p) 
{ 
2002/0316    
	DENTER("%.*s%d edf_deadline\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edf_deadline\n", m->machno); 
2002/0315    
	/* Task has reached its deadline */ 
	ilock(&edflock); 
	now = fastticks(nil); 
	edfdeadline(p, SYield); 
	iunlock(&edflock); 
	DLEAVE; 
} 
 
char * 
2002/0321/sys/src/9/port/edf.c:314,3262002/0322/sys/src/9/port/edf.c:299,311
2002/0315    
		return err; 
	} 
	ilock(&edflock); 
2002/0316    
	DENTER("%.*s%d edf_admit, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edf_admit, %s, %d\n", 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){ 
2002/0316    
		DPRINT("%.*s%d edf_admitting self\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_admitting self\n", m->machno); 
2002/0315    
		/* Admitting self, fake reaching deadline */ 
		t->r = now; 
		t->t = now + t->T; 
2002/0321/sys/src/9/port/edf.c:347,3532002/0322/sys/src/9/port/edf.c:332,337
2002/0315    
			} 
		} 
	} 
	DLEAVE; 
	iunlock(&edflock); 
	qunlock(&edfschedlock); 
	return nil; 
2002/0321/sys/src/9/port/edf.c:360,3722002/0322/sys/src/9/port/edf.c:344,355
2002/0315    
 
	qlock(&edfschedlock); 
	ilock(&edflock); 
2002/0316    
	DENTER("%.*s%d edf_expel, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edf_expel, %s, %d\n", m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	now = fastticks(nil); 
	switch(t->state){ 
	case EdfUnused: 
	case EdfExpelled: 
		/* That was easy */ 
		DLEAVE; 
		iunlock(&edflock); 
		qunlock(&edfschedlock); 
		return; 
2002/0321/sys/src/9/port/edf.c:398,4042002/0322/sys/src/9/port/edf.c:381,386
2002/0315    
	t->state = EdfExpelled; 
2002/0316    
	if(devrt) devrt(t, now, SExpel); 
2002/0320    
	setdelta(); 
2002/0315    
	DLEAVE; 
	iunlock(&edflock); 
	qunlock(&edfschedlock); 
	return; 
2002/0321/sys/src/9/port/edf.c:450,4562002/0322/sys/src/9/port/edf.c:432,438
2002/0315    
	Ticks ticks; 
	Task *t; 
 
2002/0316    
	DENTER("%.*s%d edf_setclock\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edf_setclock\n", m->machno); 
2002/0315    
	ticks = ~0ULL; 
	if ((t = qwaitrelease.head) && t->r < ticks) 
		ticks = t->r; 
2002/0321/sys/src/9/port/edf.c:461,4862002/0322/sys/src/9/port/edf.c:443,466
2002/0315    
			ticks = now + t->S; 
	} 
	if (schedpoint.when > now && schedpoint.when <= ticks){ 
		DLEAVE; 
		return; 
	} 
	if (schedpoint.when){ 
2002/0316    
		DPRINT("%.*s%d cycintrdel %T\n", ind, tabs, m->machno, ticks2time(schedpoint.when)); 
2002/0322    
		DPRINT("%d cycintrdel %T\n", m->machno, ticks2time(schedpoint.when)); 
2002/0315    
		cycintrdel(&schedpoint); 
		schedpoint.when = 0; 
	} 
	if (ticks <= now){ 
2002/0316    
		DPRINT("%.*s%d edf_timer: %T too late\n", ind, tabs, m->machno, ticks2time(now-ticks)); 
2002/0322    
		DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-ticks)); 
2002/0315    
		ticks = now; 
	} 
	if (ticks != ~0ULL) { 
2002/0316    
		DPRINT("%.*s%d program timer in %T\n", ind, tabs, m->machno, ticks2time(ticks-now)); 
2002/0322    
		DPRINT("%d program timer in %T\n", m->machno, ticks2time(ticks-now)); 
2002/0315    
		schedpoint.when = ticks; 
		cycintradd(&schedpoint); 
2002/0316    
		DPRINT("%.*s%d cycintradd %T\n", ind, tabs, m->machno, ticks2time(schedpoint.when-now)); 
2002/0322    
		DPRINT("%d cycintradd %T\n", m->machno, ticks2time(schedpoint.when-now)); 
2002/0315    
	} 
	clockintrsched(); 
	DLEAVE; 
} 
	 
static void 
2002/0321/sys/src/9/port/edf.c:487,4932002/0322/sys/src/9/port/edf.c:467,473
2002/0315    
edf_intr(Ureg *, Cycintr *cy) 
{ 
 
2002/0316    
	DENTER("%.*s%d edf_intr\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edf_intr\n", m->machno); 
2002/0315    
	/* Timer interrupt 
	 * Timed events are: 
	 * 1. release a task (look in qwaitrelease) 
2002/0321/sys/src/9/port/edf.c:504,5102002/0322/sys/src/9/port/edf.c:484,489
2002/0315    
	edf_timer(); 
	edf_setclock(); 
	iunlock(&edflock); 
	DLEAVE; 
	sched(); 
	splhi(); 
} 
2002/0321/sys/src/9/port/edf.c:515,5272002/0322/sys/src/9/port/edf.c:494,506
2002/0315    
	Task *t; 
	Proc **pp; 
 
2002/0316    
	DPRINT("%.*s%d edf_bury\n", ind, tabs, m->machno); 
2002/0322    
	DPRINT("%d edf_bury\n", m->machno); 
2002/0315    
	ilock(&edflock); 
	now = fastticks(nil); 
	if ((t = p->task) == nil){ 
		/* race condition? */ 
		iunlock(&edflock); 
2002/0316    
		DPRINT("%.*s%d edf bury race, pid %lud\n", ind, tabs, m->machno, p->pid); 
2002/0322    
		DPRINT("%d edf bury race, pid %lud\n", m->machno, p->pid); 
2002/0315    
		return; 
	} 
	assert(edfstack[m->machno].head == t); 
2002/0321/sys/src/9/port/edf.c:549,5592002/0322/sys/src/9/port/edf.c:528,538
2002/0315    
	Task *t; 
 
	ilock(&edflock); 
2002/0316    
	DENTER("%.*s%d edf_ready, %s, %d\n", ind, tabs, m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0322    
	DPRINT("%d edf_ready, %s, %d\n", m->machno, edf_statename[p->task->state], p->task->runq.n); 
2002/0315    
	if ((t = p->task) == nil){ 
		/* Must be a race */ 
		iunlock(&edflock); 
2002/0316    
		DPRINT("%.*s%d edf ready race, pid %lud\n", ind, tabs, m->machno, p->pid); 
2002/0322    
		DPRINT("%d edf ready race, pid %lud\n", m->machno, p->pid); 
2002/0315    
		return; 
	} 
	p->rnext = 0; 
2002/0321/sys/src/9/port/edf.c:571,5772002/0322/sys/src/9/port/edf.c:550,555
2002/0315    
		now = fastticks(nil); 
		edf_resched(t); 
	} 
	DLEAVE; 
	iunlock(&edflock); 
} 
 
2002/0321/sys/src/9/port/edf.c:580,5862002/0322/sys/src/9/port/edf.c:558,564
2002/0315    
{ 
	Task *xt; 
 
2002/0316    
	DENTER("%.*s%d edf_resched, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edf_resched, %s, %d\n", m->machno, edf_statename[t->state], t->runq.n); 
2002/0315    
	if (t->nproc == 0){ 
		/* No member processes */ 
		if (t->state > EdfIdle){ 
2002/0321/sys/src/9/port/edf.c:587,5982002/0322/sys/src/9/port/edf.c:565,575
2002/0315    
			t->state = EdfIdle; 
2002/0316    
			if(devrt) devrt(t, now, SBlock); 
2002/0315    
		} 
		DLEAVE; 
		return; 
	} 
	if (t->runq.n == 0 && (up == nil || up->task != t)){ 
		/* Member processes but none runnable */ 
2002/0316    
		DPRINT("%.*s%d edf_resched, nothing runnable\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_resched, nothing runnable\n", m->machno); 
2002/0315    
		if (t->state == EdfRunning) 
			edfpop(); 
 
2002/0321/sys/src/9/port/edf.c:600,6062002/0322/sys/src/9/port/edf.c:577,582
2002/0315    
			t->state = EdfBlocked; 
2002/0316    
			if(devrt) devrt(t, now, SBlock); 
2002/0315    
		} 
		DLEAVE; 
		return; 
	} 
 
2002/0321/sys/src/9/port/edf.c:608,6162002/0322/sys/src/9/port/edf.c:584,591
2002/0315    
 
	switch (t->state){ 
	case EdfUnused: 
2002/0316    
		iprint("%.*s%d attempt to schedule unused task\n", ind, tabs, m->machno); 
2002/0322    
		iprint("%d attempt to schedule unused task\n", m->machno); 
2002/0315    
	case EdfExpelled: 
		DLEAVE; 
		return;	/* Not admitted */ 
	case EdfIdle: 
		/* task was idle, schedule release now or later */ 
2002/0321/sys/src/9/port/edf.c:630,6362002/0322/sys/src/9/port/edf.c:605,610
2002/0315    
	case EdfAdmitted: 
		/* test whether task can be started */ 
		if (edfstack[m->machno].head != nil){ 
			DLEAVE; 
			return; 
		} 
		/* fall through */ 
2002/0321/sys/src/9/port/edf.c:637,6562002/0322/sys/src/9/port/edf.c:611,628
2002/0315    
	case EdfRunning: 
		if (t->r <= now){ 
			if (t->t < now){ 
2002/0316    
				DPRINT("%.*s%d edf_resched, rerelease\n", ind, tabs, m->machno); 
2002/0322    
				DPRINT("%d edf_resched, rerelease\n", m->machno); 
2002/0315    
				/* Period passed, rerelease */ 
				t->r = now; 
				xt = edfpop(); 
				assert(xt == t); 
				edf_release(t); 
				DLEAVE; 
				return; 
			} 
			if (now < t->d){ 
				if (t->S > 0){ 
2002/0316    
					DPRINT("%.*s%d edf_resched, resume\n", ind, tabs, m->machno); 
2002/0322    
					DPRINT("%d edf_resched, resume\n", m->machno); 
2002/0315    
					/* Running, not yet at deadline, leave it */ 
					DLEAVE; 
					return; 
				}else 
					t->d = now; 
2002/0321/sys/src/9/port/edf.c:658,6642002/0322/sys/src/9/port/edf.c:630,636
2002/0315    
			/* Released, but deadline is past, release at t->t */ 
			t->r = t->t; 
		} 
2002/0316    
		DPRINT("%.*s%d edf_resched, schedule release\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_resched, schedule release\n", m->machno); 
2002/0315    
		xt = edfpop(); 
		assert(xt == t); 
		edfenqueue(&qwaitrelease, t); 
2002/0321/sys/src/9/port/edf.c:669,6892002/0322/sys/src/9/port/edf.c:641,659
2002/0315    
	case EdfDeadline: 
		if (t->r <= now){ 
			if (t->t < now){ 
2002/0316    
				DPRINT("%.*s%d edf_resched, rerelease\n", ind, tabs, m->machno); 
2002/0322    
				DPRINT("%d edf_resched, rerelease\n", m->machno); 
2002/0315    
				/* Period passed, rerelease */ 
				t->r = now; 
				edf_release(t); 
				DLEAVE; 
				return; 
			} 
			if (now < t->d && (t->flags & Useblocking) == 0){ 
				if (t->S > 0){ 
2002/0316    
					DPRINT("%.*s%d edf_resched, resume\n", ind, tabs, m->machno); 
2002/0322    
					DPRINT("%d edf_resched, resume\n", m->machno); 
2002/0315    
					/* Released, not yet at deadline, release (again) */ 
					t->state = EdfReleased; 
					edfenqueue(&qreleased, t); 
2002/0316    
					if(devrt) devrt(t, now, SResume); 
2002/0315    
					DLEAVE; 
					return; 
				}else 
					t->d = now; 
2002/0321/sys/src/9/port/edf.c:691,7092002/0322/sys/src/9/port/edf.c:661,678
2002/0315    
			/* Released, but deadline is past, release at t->t */ 
			t->r = t->t; 
		} 
2002/0316    
		DPRINT("%.*s%d edf_resched, schedule release\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_resched, schedule release\n", m->machno); 
2002/0315    
		edfenqueue(&qwaitrelease, t); 
		t->state = EdfAwaitrelease; 
		edf_setclock(); 
		break; 
	} 
	DLEAVE; 
} 
 
void 
edf_release(Task *t) 
{ 
2002/0316    
	DENTER("%.*s%d edf_release, %s, %d\n", ind, tabs, m->machno, edf_statename[t->state], t->runq.n); 
2002/0322    
	DPRINT("%d edf_release, %s, %d\n", 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; 
2002/0321/sys/src/9/port/edf.c:713,7192002/0322/sys/src/9/port/edf.c:682,687
2002/0315    
	edfenqueue(&qreleased, t); 
2002/0316    
	if(devrt) devrt(t, now, SRelease); 
2002/0315    
	edf_setclock(); 
	DLEAVE; 
} 
 
Proc * 
2002/0321/sys/src/9/port/edf.c:728,7342002/0322/sys/src/9/port/edf.c:696,701
2002/0315    
 
	/* Figure out if the current proc should be preempted*/ 
	ilock(&edflock); 
	assert(ind < nelem(tabs)); 
	now = fastticks(nil); 
 
	/* first candidate is at the top of the stack of running procs */ 
2002/0321/sys/src/9/port/edf.c:742,7512002/0322/sys/src/9/port/edf.c:709,718
2002/0315    
		iunlock(&edflock); 
		return nil; 
	} 
	DENTER("edf_runproc %lud\n", nilcount); 
2002/0322    
	DPRINT("edf_runproc %lud\n", nilcount); 
2002/0320    
	if (nt && (t == nil || (nt->d < t->d && nt->D < t->Delta))){ 
2002/0315    
		/* released task is better than current */ 
2002/0316    
		DPRINT("%.*s%d edf_runproc: released\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_runproc: released\n", m->machno); 
2002/0315    
		edfdequeue(&qreleased); 
		assert(nt->runq.n >= 1); 
		edfpush(nt); 
2002/0321/sys/src/9/port/edf.c:753,7592002/0322/sys/src/9/port/edf.c:720,726
2002/0315    
		t = nt; 
		t->scheduled = now; 
	}else{ 
2002/0316    
		DPRINT("%.*s%d edf_runproc: current\n", ind, tabs, m->machno); 
2002/0322    
		DPRINT("%d edf_runproc: current\n", m->machno); 
2002/0315    
	} 
 
	assert (t->runq.n); 
2002/0321/sys/src/9/port/edf.c:771,7772002/0322/sys/src/9/port/edf.c:738,743
2002/0315    
		p->movetime = MACHP(0)->ticks + HZ/10; 
	p->mp = MACHP(m->machno); 
	edf_setclock(); 
	DLEAVE; 
	iunlock(&edflock); 
	return p; 
} 
2002/0321/sys/src/9/port/edf.c:781,7872002/0322/sys/src/9/port/edf.c:747,752
2002/0315    
int 
edf_waitlock(Lock *l) 
{ 
	iprint("edf_waitlock\n"); 
	ilock(&waitlock);	/* can't afford normal locks here */ 
	if (l->key == 0){ 
		/* race on lock, don't block, just return */ 
2002/0321/sys/src/9/port/edf.c:802,8082002/0322/sys/src/9/port/edf.c:767,772
2002/0315    
{ 
	Proc *p; 
 
	iprint("edf_releaselock\n"); 
	ilock(&waitlock);	/* can't afford normal locks here */ 
	if(l->edfwaiting == nil){ 
		iunlock(&waitlock); 


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