## diffname port/portclock.c 2000/1106 ## diff -e /dev/null /n/emeliedump/2000/1106/sys/src/9/port/portclock.c 0a #include "u.h" #include "../port/lib.h" #include "mem.h" #include "dat.h" #include "fns.h" #include "io.h" #include "ureg.h" void (*kproftimer)(ulong); typedef struct Clock0link Clock0link; typedef struct Clock0link { void (*clock)(void); Clock0link* link; } Clock0link; static Clock0link *clock0link; static Lock clock0lock; void addclock0link(void (*clock)(void)) { Clock0link *lp; if((lp = malloc(sizeof(Clock0link))) == 0){ print("addclock0link: too many links\n"); return; } ilock(&clock0lock); lp->clock = clock; lp->link = clock0link; clock0link = lp; iunlock(&clock0lock); } void portclock(Ureg *ur) { Clock0link *lp; m->ticks++; if(m->proc) m->proc->pc = ur->pc; if(m->inclockintr) return; /* interrupted ourself */ m->inclockintr = 1; accounttime(); if(kproftimer != nil) kproftimer(ur->pc); if((active.machs&(1<machno)) == 0) return; if(active.exiting && (active.machs & (1<machno))) { print("someone's exiting\n"); exit(0); } checkalarms(); if(m->machno == 0){ ilock(&clock0lock); for(lp = clock0link; lp; lp = lp->link){ lp->clock(); splhi(); } iunlock(&clock0lock); } m->inclockintr = 0; if(up == 0 || up->state != Running) return; if(anyready()) sched(); /* user profiling clock */ if(userureg(ur)) { (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); segclock(ur->pc); } } . ## diffname port/portclock.c 2000/1206 ## diff -e /n/emeliedump/2000/1106/sys/src/9/port/portclock.c /n/emeliedump/2000/1206/sys/src/9/port/portclock.c 64,69c if(canlock(&clock0lock)) for(lp = clock0link; lp; lp = lp->link){ lp->clock(); splhi(); } unlock(&clock0lock); . ## diffname port/portclock.c 2001/0328 ## diff -e /n/emeliedump/2000/1206/sys/src/9/port/portclock.c /n/emeliedump/2001/0328/sys/src/9/port/portclock.c 84a m->inclockintr = 0; . 75a } . 72,74c if(up == 0 || up->state != Running){ m->inclockintr = 0; . ## diffname port/portclock.c 2001/0331 ## diff -e /n/emeliedump/2001/0328/sys/src/9/port/portclock.c /n/emeliedump/2001/0331/sys/src/9/port/portclock.c 85d 78a splhi(); } . 77c if(anyready()){ . 75d 72,73c m->inclockintr = 0; if(up == 0 || up->state != Running) . ## diffname port/portclock.c 2001/0527 ## diff -e /n/emeliedump/2001/0331/sys/src/9/port/portclock.c /n/emeliedump/2001/0527/sys/src/9/port/portclock.c 72a . 49a kmapinval(); . ## diffname port/portclock.c 2001/0711 ## diff -e /n/emeliedump/2001/0527/sys/src/9/port/portclock.c /n/emeliedump/2001/0711/sys/src/9/port/portclock.c 88a ulong TK2MS(ulong ticks) { uvlong t, hz; t = ticks; hz = HZ; t *= 1000L; t = t/hz; ticks = t; return ticks; } . ## diffname port/portclock.c 2001/0905 ## diff -e /n/emeliedump/2001/0711/sys/src/9/port/portclock.c /n/emeliedump/2001/0905/sys/src/9/port/portclock.c 89,101d ## diffname port/portclock.c 2002/0315 ## diff -e /n/emeliedump/2001/0905/sys/src/9/port/portclock.c /n/emeliedump/2002/0315/sys/src/9/port/portclock.c 78c // i.e. don't schedule an EDF process here! if(!isedf(up) && anyready()){ . 7a #include "../port/edf.h" . ## diffname port/portclock.c 2002/0402 ## diff -e /n/emeliedump/2002/0315/sys/src/9/port/portclock.c /n/emeliedump/2002/0402/sys/src/9/port/portclock.c 78,83d 8d ## diffname port/portclock.c 2002/0404 ## diff -e /n/emeliedump/2002/0402/sys/src/9/port/portclock.c /n/emeliedump/2002/0404/sys/src/9/port/portclock.c 76a // i.e. don't schedule an EDF process here! if(!isedf(up) && anyready()){ sched(); splhi(); } . 7a #include "../port/edf.h" . ## diffname port/portclock.c 2002/0410 ## diff -e /n/emeliedump/2002/0404/sys/src/9/port/portclock.c /n/emeliedump/2002/0410/sys/src/9/port/portclock.c 89a } void timerintr(Ureg *u, uvlong) { Timer *t; Timers *tt; uvlong when, now; int callhzclock; intrcount[m->machno]++; callhzclock = 0; tt = &timers[m->machno]; now = (uvlong)fastticks(nil); ilock(tt); while(t = tt->head){ when = t->when; if(when > now){ iunlock(tt); timerset(when); if(callhzclock) hzclock(u); return; } tt->head = t->next; fcallcount[m->machno]++; iunlock(tt); if (t->f){ (*t->f)(u, t); splhi(); } else callhzclock++; ilock(tt); if(t->period){ t->when += t->period; if (t->when <= now) t->when = now + t->period; tadd(tt, t); } } iunlock(tt); } uvlong hzperiod; void timersinit(void) { Timer *t; hzperiod = ms2fastticks(1000/HZ); t = smalloc(sizeof(*t)); t->period = hzperiod; t->f = nil; timeradd(t); } void addclock0link(void (*f)(void)) { Timer *nt; /* Synchronize this to hztimer: reduces # of interrupts */ nt = malloc(sizeof(Timer)); nt->when = 0; if (hzperiod == 0) hzperiod = ms2fastticks(1000/HZ); nt->period = hzperiod; nt->f = (void (*)(Ureg*, Timer*))f; ilock(&timers[0]); tadd(&timers[0], nt); /* no need to restart timer: * this one's synchronized with hztimer which is already running */ iunlock(&timers[0]); } void clockintrsched(void) { . 80c if(anyready() && !isedf(up)){ . 65,72d 49a if(m->flushmmu){ if(up) flushmmu(); m->flushmmu = 0; } . 41a tt = &timers[m->machno]; ilock(tt); when = tadd(tt, nt); if (when) timerset(when); iunlock(tt); } void timerdel(Timer *dt) { Timer *t, **last; Timers *tt; tt = &timers[m->machno]; ilock(tt); for(last = &tt->head; t = *last; last = &t->next){ if(t == dt){ *last = t->next; break; } } if (last == &tt->head && tt->head) timerset(tt->head->when); iunlock(tt); } void hzclock(Ureg *ur) { . 40c Timers *tt; uvlong when; . 38c timeradd(Timer *nt) . 36a /* add of modify a timer */ . 30,34c if(nt->when == 0){ /* Try to synchronize periods to reduce # of interrupts */ assert(nt->period); if(pt) nt->when = pt->when; else nt->when = (uvlong)fastticks(nil) + nt->period; } for(last = &tt->head; t = *last; last = &t->next){ if(t->when > nt->when) break; } nt->next = *last; *last = nt; if (last == &tt->head) return nt->when; else return 0; . 26,28c pt = nil; for(last = &tt->head; t = *last; last = &t->next){ if(t == nt){ *last = t->next; break; } if (t->period == nt->period) pt = t; . 24c Timer *t, **last, *pt; . 21,22c ulong intrcount[MAXMACH]; ulong fcallcount[MAXMACH]; static uvlong tadd(Timers *tt, Timer *nt) . 18,19c static Timers timers[MAXMACH]; . 12,16c struct Timers { Lock; Timer *head; }; . 10c typedef struct Timers Timers; . 8d ## diffname port/portclock.c 2002/0412 ## diff -e /n/emeliedump/2002/0410/sys/src/9/port/portclock.c /n/emeliedump/2002/0412/sys/src/9/port/portclock.c 130c /* i.e. don't deschedule an EDF process here! */ . ## diffname port/portclock.c 2002/0413 ## diff -e /n/emeliedump/2002/0412/sys/src/9/port/portclock.c /n/emeliedump/2002/0413/sys/src/9/port/portclock.c 218,222d 193c t = malloc(sizeof(*t)); t->when = 0; . 181a m->inclockintr = 0; . 162a m->inclockintr = 0; . 154c now = fastticks(nil); . 150a if(m->inclockintr) return; m->inclockintr = 1; . 99,102d ## diffname port/portclock.c 2002/0414 ## diff -e /n/emeliedump/2002/0413/sys/src/9/port/portclock.c /n/emeliedump/2002/0414/sys/src/9/port/portclock.c 177,178d ## diffname port/portclock.c 2002/0416 ## diff -e /n/emeliedump/2002/0414/sys/src/9/port/portclock.c /n/emeliedump/2002/0416/sys/src/9/port/portclock.c 181d 163d 147,150d 121,122d ## diffname port/portclock.c 2002/0704 ## diff -e /n/emeliedump/2002/0416/sys/src/9/port/portclock.c /n/emeliedump/2002/0704/sys/src/9/port/portclock.c 125c if(anyready() && !edf->isedf(up)){ . ## diffname port/portclock.c 2002/0710 ## diff -e /n/emeliedump/2002/0704/sys/src/9/port/portclock.c /n/emeliedump/2002/0710/sys/src/9/port/portclock.c 210a } /* * This tk2ms avoids overflows that the macro version is prone to. * It is a LOT slower so shouldn't be used if you're just converting * a delta. */ ulong tk2ms(ulong ticks) { uvlong t, hz; t = ticks; hz = HZ; t *= 1000L; t = t/hz; ticks = t; return ticks; } ulong ms2tk(ulong ms) { /* avoid overflows at the cost of precision */ if(ms >= 1000000000/HZ) return (ms/1000)*HZ; return (ms*HZ+500)/1000; . 173a intimer = 0; . 156a intimer = 0; . 144a if(intimer){ print("!"); return; } intimer = 1; . 143a static int intimer; . ## diffname port/portclock.c 2002/0711 ## diff -e /n/emeliedump/2002/0710/sys/src/9/port/portclock.c /n/emeliedump/2002/0711/sys/src/9/port/portclock.c 182d 164d 161a m->splpc = pc; /* for kernel profiling */ . 146,150c pc = m->splpc; /* remember last splhi pc for kernel profiling */ . 144c ulong pc; static int sofar; . ## diffname port/portclock.c 2002/0928 ## diff -e /n/emeliedump/2002/0711/sys/src/9/port/portclock.c /n/emeliedump/2002/0928/sys/src/9/port/portclock.c 205,207c if (ms == 0) ms = 1000/HZ; nt->period = ms2fastticks(ms); . 198c addclock0link(void (*f)(void), int ms) . 34a } . 33c if (t->period == nt->period){ /* look for another timer at same frequency for combining */ . 29a /* timer's changing, remove it before putting it back on */ . ## diffname port/portclock.c 2003/0122 ## diff -e /n/emeliedump/2002/0928/sys/src/9/port/portclock.c /n/emeliedump/2003/0122/sys/src/9/port/portclock.c 161a iunlock(tt); . 160d ## diffname port/portclock.c 2003/0226 ## diff -e /n/emeliedump/2003/0122/sys/src/9/port/portclock.c /n/emeliedump/2003/0226/sys/src/9/port/portclock.c 127,128c if(up->fixedpri){ /* fixed priority processes are only preempted by * higher piority processes. */ if(anyhigher()) callsched = 1; } else { /* floating priority processes are are preempted * by all sorts of things. */ if(anyready() && !edf->isedf(up)) callsched = 1; } if(callsched){ . 97a int callsched; . ## diffname port/portclock.c 2003/0228 ## diff -e /n/emeliedump/2003/0226/sys/src/9/port/portclock.c /n/emeliedump/2003/0228/sys/src/9/port/portclock.c 151a hzsched(); /* in proc.c */ . 148c if(userureg(ur)){ . 129,146d 98,99d ## diffname port/portclock.c 2003/0406 ## diff -e /n/emeliedump/2003/0228/sys/src/9/port/portclock.c /n/emeliedump/2003/0406/sys/src/9/port/portclock.c 204c if(ms == 0) . 166c if(t->f){ . 90c if(last == &tt->head && tt->head) . 71c if(when) . 55c if(last == &tt->head) . 34c if(t->period == nt->period){ . ## diffname port/portclock.c 2003/0409 ## diff -e /n/emeliedump/2003/0406/sys/src/9/port/portclock.c /n/emeliedump/2003/0409/sys/src/9/port/portclock.c 98a if((m->ticks % 10000) == 0){ extern int allints[]; int i; for(i=0; i < 32; i++) print("[%d] %d\n", i, allints[i]); } . ## diffname port/portclock.c 2003/0410 ## diff -e /n/emeliedump/2003/0409/sys/src/9/port/portclock.c /n/emeliedump/2003/0410/sys/src/9/port/portclock.c 99,104d