From e6f6e843ac2051282dd30af3b55fe5b75b26c26f Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 28 Mar 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-03-28 --- port/edf.c | 114 ++++++++++++++----------------------------------- port/portdat.h | 3 +- port/proc.c | 1 + port/taslock.c | 14 +----- 4 files changed, 36 insertions(+), 96 deletions(-) diff --git a/port/edf.c b/port/edf.c index 61c23b72db546768ad542015f0948c5a4c8af192..fb0d1fade088a17204108956e3f651b43334bddc 100644 --- a/port/edf.c +++ b/port/edf.c @@ -33,8 +33,7 @@ static Ticks utilization; /* Current utilization */ static int initialized; static uvlong fasthz; static Ticks now; -QLock edfschedlock; /* schedulability, held for - */ +QLock edfschedlock; Lock edflock; Task tasks[Maxtasks]; @@ -68,12 +67,12 @@ Taskq edfstack[MAXMACH]; void (*devrt)(Task*, Ticks, int); -static void edfdeadlineintr(Ureg*, Cycintr*); static void edf_resched(Task *t); static void setdelta(void); static void testdelta(Task *thetask); static char * edf_testschedulability(Task *thetask); -static void edfreleaseintr(void); +static void edfreleaseintr(Ureg *, Cycintr *cy); +static void edfdeadlineintr(Ureg*, Cycintr*); void edf_init(void) @@ -211,6 +210,7 @@ edfqremove(Taskq *q, Task *t) } } iunlock(q); + return nil; } @@ -219,37 +219,18 @@ edfreleasetimer(void) { Task *t; - t = qwaitrelease.head; - DPRINT("edf_schedrelease clock\n"); - if (cycrelease.when == t->r) + if ((t = qwaitrelease.head) == nil) return; - if (cycrelease.when){ - DPRINT("%d cycintrdel %T\n", m->machno, ticks2time(cycrelease.when)); + DPRINT("edfreleasetimer clock\n"); + if (cycrelease.when) cycintrdel(&cycrelease); - } cycrelease.when = t->r; - if (cycrelease.when <= now){ - DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-ticks)); + if (cycrelease.when <= now) 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 edf_block(Proc *p) { @@ -434,19 +415,23 @@ edf_expel(Task *t) } static void -edfreleaseintr(void) +edfreleaseintr(Ureg*, Cycintr*) { Task *t; - now = fastticks(nil); + DPRINT("%d edfreleaseintr\n", m->machno); + + cycrelease.when = 0; if(active.exiting) return; ilock(&edflock); + now = fastticks(nil); while((t = qwaitrelease.head) && t->r <= now){ /* There's something waiting to be released and its time has come */ edfdequeue(&qwaitrelease); + edfreleasetimer(); edf_release(t); } iunlock(&edflock); @@ -455,15 +440,16 @@ edfreleaseintr(void) } static void -edfdeadlineintr(Ureg *, Cycintr *cy) +edfdeadlineintr(Ureg*, Cycintr*) { + /* Task reached deadline */ + Ticks used; Task *t; DPRINT("%d edfdeadlineintr\n", m->machno); - /* Task reached deadline - */ - now = fastticks(nil); + + cycdeadline.when = 0; if(active.exiting) return; @@ -472,6 +458,8 @@ edfdeadlineintr(Ureg *, Cycintr *cy) // If up is not set, we're running inside the scheduler // for non-real-time processes. if (up && isedf(up)) { + now = fastticks(nil); + t = up->task; assert(t->scheduled > 0); @@ -644,7 +632,9 @@ edf_resched(Task *t) } xt = edfpop(); assert(xt == t); - schedrelease(t); + t->state = EdfAwaitrelease; + if (edfenqueue(&qwaitrelease, t)) + edfreleasetimer(); break; case EdfBlocked: case EdfDeadline: @@ -670,7 +660,9 @@ edf_resched(Task *t) /* Released, but deadline is past, release at t->t */ t->r = t->t; } - schedrelease(t); + t->state = EdfAwaitrelease; + if (edfenqueue(&qwaitrelease, t)) + edfreleasetimer(); break; } } @@ -747,68 +739,24 @@ edf_runproc(void) if (t->d < when) when = t->d; + if (when < now){ + DPRINT("%d edf_timer: %T too late\n", m->machno, ticks2time(now-when)); + when = now; + } 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(); 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 */ static void diff --git a/port/portdat.h b/port/portdat.h index 327210619f039bf208ce66f146d63010ceb836de..ccb09f06fecb6f0495e2955189afe260bbcc1d36 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -635,10 +635,11 @@ struct Proc Note lastnote; int (*notify)(void*, char*); - Lock *lockwait; /* waiting for lock to be released */ + Lock *lockwait; Mach *wired; Mach *mp; /* machine this process last ran on */ + ulong nlocks; /* number of locks held by proc */ ulong priority; /* priority level */ ulong basepri; /* base priority level */ uchar fixedpri; /* priority level deson't change */ diff --git a/port/proc.c b/port/proc.c index a1d82d3c9225d5912034d69e4c009be9bd7aac1c..2371fd50d9dda4dfc1a091e34134d4d9c847fa53 100644 --- a/port/proc.c +++ b/port/proc.c @@ -347,6 +347,7 @@ newproc(void) p->wired = 0; p->ureg = 0; p->privatemem = 0; + p->lockwait = nil; p->errstr = p->errbuf0; p->syserrstr = p->errbuf1; p->errbuf0[0] = '\0'; diff --git a/port/taslock.c b/port/taslock.c index 4e35996323b43b0c993b69d965de6f34751f8915..b289750fe4059a205f9b02bbe57f790092960237 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -72,16 +72,8 @@ lock(Lock *l) lockstats.inglare++; i = 0; while(l->key){ - if (isedf(up)){ - /* Edf process waiting for a lock; process holding lock will not - * be scheduled unless we give up the processor. We give up - * the processor, but make sure we get awoken when the lock - * is released - */ - if (edf_waitlock(l)) - sched(); - } else if(conf.nmach < 2 && cansched){ - if (i++ > 5000){ + if(conf.nmach < 2 && cansched){ + if (i++ > 1000){ i = 0; lockloop(l, pc); } @@ -181,8 +173,6 @@ unlock(Lock *l) l->pc = 0; l->key = 0; coherence(); - if (l->edfwaiting) - edf_releaselock(l); } void