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

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

2002/0327/sys/src/9/port/edf.c:33,402002/0328/sys/src/9/port/edf.c:33,39 (short | long | prev | next)
2002/0315    
static int		initialized; 
static uvlong	fasthz;	 
static Ticks	now; 
QLock		edfschedlock;		/* schedulability, held for 
							 */ 
2002/0328    
QLock		edfschedlock; 
2002/0315    
Lock			edflock; 
 
Task			tasks[Maxtasks]; 
2002/0327/sys/src/9/port/edf.c:68,792002/0328/sys/src/9/port/edf.c:67,78
2002/0315    
 
2002/0316    
void (*devrt)(Task*, Ticks, int); 
2002/0315    
 
2002/0327    
static void		edfdeadlineintr(Ureg*, Cycintr*); 
2002/0315    
static void		edf_resched(Task *t); 
2002/0320    
static void		setdelta(void); 
static void		testdelta(Task *thetask); 
2002/0315    
static char *	edf_testschedulability(Task *thetask); 
2002/0327    
static void		edfreleaseintr(void); 
2002/0328    
static void		edfreleaseintr(Ureg *, Cycintr *cy); 
static void		edfdeadlineintr(Ureg*, Cycintr*); 
2002/0315    
 
void 
edf_init(void) 
2002/0327/sys/src/9/port/edf.c:211,2162002/0328/sys/src/9/port/edf.c:210,216
2002/0315    
		} 
	} 
	iunlock(q); 
2002/0328    
	return nil; 
2002/0315    
} 
 
2002/0327    
			 
2002/0327/sys/src/9/port/edf.c:219,2562002/0328/sys/src/9/port/edf.c:219,237
2002/0327    
{ 
	Task *t; 
 
	t = qwaitrelease.head; 
	DPRINT("edf_schedrelease clock\n"); 
	if (cycrelease.when == t->r) 
2002/0328    
	if ((t = qwaitrelease.head) == nil) 
2002/0327    
		return; 
	if (cycrelease.when){ 
		DPRINT("%d cycintrdel %T\n", m->machno, ticks2time(cycrelease.when)); 
2002/0328    
	DPRINT("edfreleasetimer clock\n"); 
	if (cycrelease.when) 
2002/0327    
		cycintrdel(&cycrelease); 
	} 
	cycrelease.when = t->r; 
	if (cycrelease.when <= now){ 
		DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-ticks)); 
2002/0328    
	if (cycrelease.when <= now) 
2002/0327    
		cycrelease.when = now; 
	} 
	DPRINT("%d program timer in %T\n", m->machno, ticks2time(ticks-now)); 
	cycintradd(&cycrelease); 
	DPRINT("%d cycintradd %T\n", m->machno, ticks2time(cycrelease.when-now)); 
	clockintrsched(); 
} 
 
void 
edf_schedrelease(Task *t) 
{ 
	Ticks ticks; 
                 
	DPRINT("%d edf_schedrelease\n", m->machno); 
	/* Schedule a task for release */ 
	t->state = EdfAwaitrelease; 
	if (edfenqueue(&qwaitrelease, t)) 
		edfreleasetimer(); 
} 
                 
void 
2002/0315    
edf_block(Proc *p) 
{ 
	Task *t, *pt; 
2002/0327/sys/src/9/port/edf.c:434,4522002/0328/sys/src/9/port/edf.c:415,437
2002/0315    
} 
 
static void 
2002/0327    
edfreleaseintr(void) 
2002/0328    
edfreleaseintr(Ureg*, Cycintr*) 
2002/0315    
{ 
2002/0327    
	Task *t; 
 
	now = fastticks(nil); 
2002/0328    
	DPRINT("%d edfreleaseintr\n", m->machno); 
2002/0327    
 
2002/0328    
	cycrelease.when = 0; 
 
2002/0327    
	if(active.exiting) 
		return; 
 
	ilock(&edflock); 
2002/0328    
	now = fastticks(nil); 
2002/0327    
	while((t = qwaitrelease.head) && t->r <= now){ 
		/* There's something waiting to be released and its time has come */ 
		edfdequeue(&qwaitrelease); 
2002/0328    
		edfreleasetimer(); 
2002/0327    
		edf_release(t); 
	} 
	iunlock(&edflock); 
2002/0327/sys/src/9/port/edf.c:455,4702002/0328/sys/src/9/port/edf.c:440,456
2002/0327    
} 
 
static void 
edfdeadlineintr(Ureg *, Cycintr *cy) 
2002/0328    
edfdeadlineintr(Ureg*, Cycintr*) 
2002/0327    
{ 
2002/0328    
	/* Task reached deadline */ 
 
2002/0315    
	Ticks used; 
	Task *t; 
 
2002/0327    
	DPRINT("%d edfdeadlineintr\n", m->machno); 
	/* Task reached deadline 
	 */ 
	now = fastticks(nil); 
 
2002/0328    
	cycdeadline.when = 0; 
 
2002/0327    
	if(active.exiting) 
		return; 
 
2002/0327/sys/src/9/port/edf.c:472,4772002/0328/sys/src/9/port/edf.c:458,465
2002/0315    
	// If up is not set, we're running inside the scheduler 
	// for non-real-time processes.  
	if (up && isedf(up)) { 
2002/0328    
		now = fastticks(nil); 
 
2002/0315    
		t = up->task; 
		assert(t->scheduled > 0); 
	 
2002/0327/sys/src/9/port/edf.c:644,6502002/0328/sys/src/9/port/edf.c:632,640
2002/0315    
		} 
		xt = edfpop(); 
		assert(xt == t); 
2002/0327    
		schedrelease(t); 
2002/0328    
		t->state = EdfAwaitrelease; 
		if (edfenqueue(&qwaitrelease, t)) 
			edfreleasetimer(); 
2002/0315    
		break; 
	case EdfBlocked: 
	case EdfDeadline: 
2002/0327/sys/src/9/port/edf.c:670,6762002/0328/sys/src/9/port/edf.c:660,668
2002/0315    
			/* Released, but deadline is past, release at t->t */ 
			t->r = t->t; 
		} 
2002/0327    
		schedrelease(t); 
2002/0328    
		t->state = EdfAwaitrelease; 
		if (edfenqueue(&qwaitrelease, t)) 
			edfreleasetimer(); 
2002/0315    
		break; 
	} 
} 
2002/0327/sys/src/9/port/edf.c:747,8132002/0328/sys/src/9/port/edf.c:739,761
2002/0327    
	if (t->d < when) 
		when = t->d; 
 
2002/0328    
	if (when < now){ 
		DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-when)); 
		when = now; 
	} 
2002/0327    
	if (cycdeadline.when){ 
		if(cycdeadline.when == when){ 
			iunlock(&edflock); 
			return p; 
		} 
		DPRINT("%d cycintrdel %T\n", m->machno, ticks2time(cycdeadline.when)); 
		cycintrdel(&cycdeadline); 
	} 
	if (when <= now){ 
		DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-when)); 
		when = now; 
	} 
	DPRINT("%d program timer in %T\n", m->machno, ticks2time(when-now)); 
	cycdeadline.when = when; 
	cycintradd(&cycdeadline); 
	DPRINT("%d cycintradd %T\n", m->machno, ticks2time(cycdeadline.when-now)); 
	clockintrsched(); 
2002/0315    
	iunlock(&edflock); 
	return p; 
} 
                 
static Lock	waitlock; 
                 
int 
edf_waitlock(Lock *l) 
{ 
	ilock(&waitlock);	/* can't afford normal locks here */ 
	if (l->key == 0){ 
		/* race on lock, don't block, just return */ 
		iunlock(&waitlock); 
		return 0; 
	} 
	edf_block(up); 
	up->rnext = l->edfwaiting;	/* enqueue on lock */ 
	l->edfwaiting = up; 
	up->state = Scheding; 
	up->lockwait = l; 
	iunlock(&waitlock); 
	return 1; 
} 
                 
void 
edf_releaselock(Lock *l) 
{ 
	Proc *p; 
                 
	ilock(&waitlock);	/* can't afford normal locks here */ 
	if(l->edfwaiting == nil){ 
		iunlock(&waitlock); 
		return; 
	} 
	p = l->edfwaiting; 
	l->edfwaiting = p->rnext; 
	assert(p->lockwait == l); 
	if(p->state != Scheding) 
		print("edf_releaselock: %s %lud %s\n", p->text, p->pid, statename[p->state]); 
	p->lockwait = nil; 
	iunlock(&waitlock); 
	edf_ready(p); 
} 
                 
 
/* Schedulability testing and its supporting routines */ 
 


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