2 #include "../port/lib.h"
15 static Timers timers[MAXMACH];
17 ulong intrcount[MAXMACH];
18 ulong fcallcount[MAXMACH];
21 tadd(Timers *tt, Timer *nt)
25 /* Called with tt locked */
26 assert(nt->tt == nil);
34 nt->twhen = fastticks(nil) + ns2fastticks(nt->tns);
37 assert(nt->tns >= 100000); /* At least 100 µs period */
39 /* look for another timer at same frequency for combining */
40 for(t = tt->head; t; t = t->tnext){
41 if(t->tmode == Tperiodic && t->tns == nt->tns)
47 nt->twhen = fastticks(nil);
49 nt->twhen += ns2fastticks(nt->tns);
53 for(last = &tt->head; t = *last; last = &t->tnext){
54 if(t->twhen > nt->twhen)
75 for(last = &tt->head; t = *last; last = &t->tnext){
83 if(last == &tt->head && tt->head)
84 return tt->head->twhen;
88 /* add or modify a timer */
95 /* Must lock Timer struct before Timers struct */
102 tt = &timers[m->machno];
122 if(when && tt == &timers[m->machno])
123 timerset(tt->head->twhen);
134 m->proc->pc = ur->pc;
145 if(kproftimer != nil)
148 if((active.machs&(1<<m->machno)) == 0)
152 print("someone's exiting\n");
159 if(up && up->state == Running)
160 hzsched(); /* in proc.c */
164 timerintr(Ureg *u, Tval)
172 intrcount[m->machno]++;
174 tt = &timers[m->machno];
175 now = fastticks(nil);
179 * No need to ilock t here: any manipulation of t
180 * requires tdel(t) and this must be done with a
181 * lock to tt held. We have tt, so the tdel will
182 * wait until we're done
195 fcallcount[m->machno]++;
202 if(t->tmode == Tperiodic)
214 * T->tf == nil means the HZ clock for this processor.
217 t = malloc(sizeof(*t));
219 panic("timersinit: no memory for Timer");
220 t->tmode = Tperiodic;
222 t->tns = 1000000000/HZ;
228 addclock0link(void (*f)(void), int ms)
233 /* Synchronize to hztimer if ms is 0 */
234 nt = malloc(sizeof(Timer));
236 panic("addclock0link: no memory for Timer");
239 nt->tns = (vlong)ms*1000000LL;
240 nt->tmode = Tperiodic;
242 nt->tf = (void (*)(Ureg*, Timer*))f;
245 when = tadd(&timers[0], nt);
253 * This tk2ms avoids overflows that the macro version is prone to.
254 * It is a LOT slower so shouldn't be used if you're just converting
273 /* avoid overflows at the cost of precision */
274 if(ms >= 1000000000/HZ)
276 return (ms*HZ+500)/1000;