| plan 9 kernel history: overview | file list | diff list |
2002/0831/port/edf.c (diff list | history)
| 2002/0704/sys/src/9/port/edf.c:32,44 – 2002/0831/sys/src/9/port/edf.c:32,43 (short | long | prev | next) | ||
| 2002/0315 | static int initialized; static uvlong fasthz; static Ticks now; | |
| 2002/0831 | /* Edfschedlock protects modification of sched params, including resources */ | |
| 2002/0328 | QLock edfschedlock; | |
| 2002/0315 | Lock edflock; | |
| 2002/0831 | Head tasks; Head resources; | |
| 2002/0410 | int edfstateupdate; | |
| 2002/0420 | int misseddeadlines; | |
| 2002/0315 | ||
| 2002/0704/sys/src/9/port/edf.c:301,306 – 2002/0831/sys/src/9/port/edf.c:300,306 | ||
| 2002/0315 | { char *err; | |
| 2002/0831 | /* Called with edfschedlock held */ | |
| 2002/0315 | if (t->state != EdfExpelled) return "task state"; /* should never happen */ | |
| 2002/0316 | ||
| 2002/0704/sys/src/9/port/edf.c:316,327 – 2002/0831/sys/src/9/port/edf.c:316,326 | ||
| 2002/0316 | if (t->C > t->D) return "C > D"; | |
| 2002/0315 |
| |
| 2002/0410 | if (err = edftestschedulability(t)){ | |
| 2002/0315 |
| |
| 2002/0831 | qunlock(&edfschedlock); | |
| 2002/0410 | DPRINT("%d edfadmit, %s, %d\n", m->machno, edfstatename[t->state], t->runq.n); | |
| 2002/0315 | now = fastticks(nil); | |
| 2002/0704/sys/src/9/port/edf.c:358,364 – 2002/0831/sys/src/9/port/edf.c:357,363 | ||
| 2002/0315 | } } iunlock(&edflock); | |
| 2002/0831 | qlock(&edfschedlock); | |
| 2002/0315 | return nil; } | |
| 2002/0704/sys/src/9/port/edf.c:367,373 – 2002/0831/sys/src/9/port/edf.c:366,372 | ||
| 2002/0315 | { Task *tt; | |
| 2002/0831 | /* Called with edfschedlock held */ | |
| 2002/0315 | ilock(&edflock); | |
| 2002/0410 | DPRINT("%d edfexpel, %s, %d\n", m->machno, edfstatename[t->state], t->runq.n); | |
| 2002/0315 | now = fastticks(nil); | |
| 2002/0704/sys/src/9/port/edf.c:376,382 – 2002/0831/sys/src/9/port/edf.c:375,380 | ||
| 2002/0315 | case EdfExpelled: /* That was easy */ iunlock(&edflock); | |
| 2002/0704/sys/src/9/port/edf.c:408,414 – 2002/0831/sys/src/9/port/edf.c:406,411 | ||
| 2002/0316 | if(devrt) devrt(t, now, SExpel); | |
| 2002/0320 | setdelta(); | |
| 2002/0315 | iunlock(&edflock); | |
| 2002/0704/sys/src/9/port/edf.c:497,503 – 2002/0831/sys/src/9/port/edf.c:494,499 | ||
| 2002/0410 | edfbury(Proc *p) | |
| 2002/0315 | { Task *t; | |
| 2002/0410 | DPRINT("%d edfbury\n", m->machno); | |
| 2002/0315 | ilock(&edflock); | |
| 2002/0704/sys/src/9/port/edf.c:509,524 – 2002/0831/sys/src/9/port/edf.c:505,516 | ||
| 2002/0315 | return; } assert(edfstack[m->machno].head == t); | |
| 2002/0831 | delist(&t->procs, p); | |
| 2002/0315 | if (t->runq.head == nil){ edfpop(); t->state = EdfBlocked; } | |
| 2002/0831 | if (t->procs.n == 0){ | |
| 2002/0315 | assert(t->runq.head == nil); t->state = EdfIdle; } | |
| 2002/0704/sys/src/9/port/edf.c:564,570 – 2002/0831/sys/src/9/port/edf.c:556,562 | ||
| 2002/0315 | Task *xt; | |
| 2002/0410 | DPRINT("%d edfresched, %s, %d\n", m->machno, edfstatename[t->state], t->runq.n); | |
| 2002/0315 |
| |
| 2002/0831 | if (t->procs.n == 0){ | |
| 2002/0315 | /* No member processes */ if (t->state > EdfIdle){ t->state = EdfIdle; | |
| 2002/0704/sys/src/9/port/edf.c:788,811 – 2002/0831/sys/src/9/port/edf.c:780,812 | ||
| 2002/0315 | static void | |
| 2002/0320 | setdelta(void) | |
| 2002/0315 | { | |
| 2002/0831 | Resource *r; Task *t; List *lr, *lt; | |
| 2002/0315 |
| |
| 2002/0831 | for (lr = resources.next; lr; lr = lr->next){ r = lr->i; assert(r); | |
| 2002/0320 | r->Delta = ~0LL; | |
| 2002/0315 |
| |
| 2002/0320 |
| |
| 2002/0831 | for (lt = r->tasks.next; lt; lt = lt->next){ t = lt->i; assert(t); if (t->D < r->Delta) r->Delta = t->D; } | |
| 2002/0315 | } | |
| 2002/0831 | for (lt = tasks.next; lt ; lt = lt->next){ t = lt->i; assert(t); | |
| 2002/0315 | if (t->state < EdfIdle) continue; | |
| 2002/0320 | t->Delta = t->D; | |
| 2002/0315 |
| |
| 2002/0320 |
| |
| 2002/0831 | for (lr = t->res.next; lr; lr = lr->next){ r = lr->i; assert(r); if (r->Delta < t->Delta) t->Delta = r->Delta; } | |
| 2002/0315 | } } | |
| 2002/0704/sys/src/9/port/edf.c:812,835 – 2002/0831/sys/src/9/port/edf.c:813,845 | ||
| 2002/0315 | static void | |
| 2002/0320 | testdelta(Task *thetask) | |
| 2002/0315 | { | |
| 2002/0831 | Resource *r; Task *t; List *lr, *lt; | |
| 2002/0315 |
| |
| 2002/0831 | for (lr = resources.next; lr; lr = lr->next){ r = lr->i; assert(r); | |
| 2002/0320 | r->testDelta = ~0ULL; | |
| 2002/0315 |
| |
| 2002/0320 |
| |
| 2002/0831 | for (lt = r->tasks.next; lt; lt = lt->next){ t = lt->i; assert(t); if (t->D < r->testDelta) r->testDelta = t->D; } | |
| 2002/0315 | } | |
| 2002/0831 | for (lt = tasks.next; lt ; lt = lt->next){ t = lt->i; assert(t); | |
| 2002/0315 | if (t->state <= EdfExpelled && t != thetask) continue; | |
| 2002/0320 | t->testDelta = t->D; | |
| 2002/0315 |
| |
| 2002/0320 |
| |
| 2002/0831 | for (lr = t->res.next; lr; lr = lr->next){ r = lr->i; assert(r); if (r->testDelta < t->testDelta) t->testDelta = r->testDelta; } | |
| 2002/0315 | } } | |
| 2002/0704/sys/src/9/port/edf.c:838,846 – 2002/0831/sys/src/9/port/edf.c:848,859 | ||
| 2002/0315 | { Task *t; Ticks Cb; | |
| 2002/0831 | List *lt; | |
| 2002/0315 | Cb = 0; | |
| 2002/0831 | for (lt = tasks.next; lt ; lt = lt->next){ t = lt->i; assert(t); | |
| 2002/0315 | if (t->state <= EdfExpelled && t != thetask) continue; | |
| 2002/0320 | if (t->testDelta <= ticks && ticks < t->D && Cb < t->C) | |
| 2002/0704/sys/src/9/port/edf.c:881,886 – 2002/0831/sys/src/9/port/edf.c:894,900 | ||
| 2002/0315 | Task *t; Ticks H, G, Cb, ticks; int steps; | |
| 2002/0831 | List *l; | |
| 2002/0315 | /* initialize */ | |
| 2002/0320 | testdelta(thetask); | |
| 2002/0704/sys/src/9/port/edf.c:887,899 – 2002/0831/sys/src/9/port/edf.c:901,915 | ||
| 2002/0315 | if (thetask && (thetask->flags & Verbose)) pprint("schedulability test\n"); qschedulability = nil; | |
| 2002/0831 | for (l = tasks.next; l; l = l->next){ t = l->i; assert(t); | |
| 2002/0315 | if (t->state <= EdfExpelled && t != thetask) continue; t->testtype = Release; t->testtime = 0; if (thetask && (thetask->flags & Verbose)) | |
| 2002/0831 | pprint("\tInit: enqueue task %lud\n", t->taskno); | |
| 2002/0315 | testenq(t); } H=0; | |
| 2002/0704/sys/src/9/port/edf.c:908,914 – 2002/0831/sys/src/9/port/edf.c:924,930 | ||
| 2002/0315 | Cb = blockcost(ticks, thetask); if (thetask && (thetask->flags & Verbose)) pprint("\tStep %3d, Ticks %T, task %lud, deadline, H += %T → %T, Cb = %T\n", | |
| 2002/0831 | steps, ticks2time(ticks), t->taskno, | |
| 2002/0315 | ticks2time(t->C), ticks2time(H), ticks2time(Cb)); if (H+Cb>ticks) return "not schedulable"; | |
| 2002/0704/sys/src/9/port/edf.c:919,925 – 2002/0831/sys/src/9/port/edf.c:935,941 | ||
| 2002/0315 | case Release: if (thetask && (thetask->flags & Verbose)) pprint("\tStep %3d, Ticks %T, task %lud, release, G %T, C%T\n", | |
| 2002/0831 | steps, ticks2time(ticks), t->taskno, | |
| 2002/0315 | ticks2time(t->C), ticks2time(G)); if(ticks && G <= ticks) return nil; | |