1*7dd7cddfSDavid du Colombier #include <u.h> 2*7dd7cddfSDavid du Colombier #include <libc.h> 3*7dd7cddfSDavid du Colombier #include <draw.h> 4*7dd7cddfSDavid du Colombier #include <thread.h> 5*7dd7cddfSDavid du Colombier #include <cursor.h> 6*7dd7cddfSDavid du Colombier #include <mouse.h> 7*7dd7cddfSDavid du Colombier #include <keyboard.h> 8*7dd7cddfSDavid du Colombier #include <frame.h> 9*7dd7cddfSDavid du Colombier #include <auth.h> 10*7dd7cddfSDavid du Colombier #include <fcall.h> 11*7dd7cddfSDavid du Colombier #include "dat.h" 12*7dd7cddfSDavid du Colombier #include "fns.h" 13*7dd7cddfSDavid du Colombier 14*7dd7cddfSDavid du Colombier static Channel* ctimer; /* chan(Timer*)[100] */ 15*7dd7cddfSDavid du Colombier static Timer *timer; 16*7dd7cddfSDavid du Colombier 17*7dd7cddfSDavid du Colombier static 18*7dd7cddfSDavid du Colombier uint 19*7dd7cddfSDavid du Colombier msec(void) 20*7dd7cddfSDavid du Colombier { 21*7dd7cddfSDavid du Colombier return nsec()/1000000; 22*7dd7cddfSDavid du Colombier } 23*7dd7cddfSDavid du Colombier 24*7dd7cddfSDavid du Colombier void 25*7dd7cddfSDavid du Colombier timerstop(Timer *t) 26*7dd7cddfSDavid du Colombier { 27*7dd7cddfSDavid du Colombier t->next = timer; 28*7dd7cddfSDavid du Colombier timer = t; 29*7dd7cddfSDavid du Colombier } 30*7dd7cddfSDavid du Colombier 31*7dd7cddfSDavid du Colombier void 32*7dd7cddfSDavid du Colombier timercancel(Timer *t) 33*7dd7cddfSDavid du Colombier { 34*7dd7cddfSDavid du Colombier t->cancel = TRUE; 35*7dd7cddfSDavid du Colombier } 36*7dd7cddfSDavid du Colombier 37*7dd7cddfSDavid du Colombier static 38*7dd7cddfSDavid du Colombier void 39*7dd7cddfSDavid du Colombier timerproc(void*) 40*7dd7cddfSDavid du Colombier { 41*7dd7cddfSDavid du Colombier int i, nt, na, dt, del; 42*7dd7cddfSDavid du Colombier Timer **t, *x; 43*7dd7cddfSDavid du Colombier uint old, new; 44*7dd7cddfSDavid du Colombier 45*7dd7cddfSDavid du Colombier rfork(RFFDG); 46*7dd7cddfSDavid du Colombier threadsetname("TIMERPROC"); 47*7dd7cddfSDavid du Colombier t = nil; 48*7dd7cddfSDavid du Colombier na = 0; 49*7dd7cddfSDavid du Colombier nt = 0; 50*7dd7cddfSDavid du Colombier old = msec(); 51*7dd7cddfSDavid du Colombier for(;;){ 52*7dd7cddfSDavid du Colombier sleep(1); /* will sleep minimum incr */ 53*7dd7cddfSDavid du Colombier new = msec(); 54*7dd7cddfSDavid du Colombier dt = new-old; 55*7dd7cddfSDavid du Colombier old = new; 56*7dd7cddfSDavid du Colombier if(dt < 0) /* timer wrapped; go around, losing a tick */ 57*7dd7cddfSDavid du Colombier continue; 58*7dd7cddfSDavid du Colombier for(i=0; i<nt; i++){ 59*7dd7cddfSDavid du Colombier x = t[i]; 60*7dd7cddfSDavid du Colombier x->dt -= dt; 61*7dd7cddfSDavid du Colombier del = 0; 62*7dd7cddfSDavid du Colombier if(x->cancel){ 63*7dd7cddfSDavid du Colombier timerstop(x); 64*7dd7cddfSDavid du Colombier del = 1; 65*7dd7cddfSDavid du Colombier }else if(x->dt <= 0){ 66*7dd7cddfSDavid du Colombier /* 67*7dd7cddfSDavid du Colombier * avoid possible deadlock if client is 68*7dd7cddfSDavid du Colombier * now sending on ctimer 69*7dd7cddfSDavid du Colombier */ 70*7dd7cddfSDavid du Colombier if(nbsendul(x->c, 0) > 0) 71*7dd7cddfSDavid du Colombier del = 1; 72*7dd7cddfSDavid du Colombier } 73*7dd7cddfSDavid du Colombier if(del){ 74*7dd7cddfSDavid du Colombier memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]); 75*7dd7cddfSDavid du Colombier --nt; 76*7dd7cddfSDavid du Colombier --i; 77*7dd7cddfSDavid du Colombier } 78*7dd7cddfSDavid du Colombier } 79*7dd7cddfSDavid du Colombier if(nt == 0){ 80*7dd7cddfSDavid du Colombier x = recvp(ctimer); 81*7dd7cddfSDavid du Colombier gotit: 82*7dd7cddfSDavid du Colombier if(nt == na){ 83*7dd7cddfSDavid du Colombier na += 10; 84*7dd7cddfSDavid du Colombier t = realloc(t, na*sizeof(Timer*)); 85*7dd7cddfSDavid du Colombier if(t == nil) 86*7dd7cddfSDavid du Colombier abort(); 87*7dd7cddfSDavid du Colombier } 88*7dd7cddfSDavid du Colombier t[nt++] = x; 89*7dd7cddfSDavid du Colombier old = msec(); 90*7dd7cddfSDavid du Colombier } 91*7dd7cddfSDavid du Colombier if(nbrecv(ctimer, &x) > 0) 92*7dd7cddfSDavid du Colombier goto gotit; 93*7dd7cddfSDavid du Colombier } 94*7dd7cddfSDavid du Colombier } 95*7dd7cddfSDavid du Colombier 96*7dd7cddfSDavid du Colombier void 97*7dd7cddfSDavid du Colombier timerinit(void) 98*7dd7cddfSDavid du Colombier { 99*7dd7cddfSDavid du Colombier ctimer = chancreate(sizeof(Timer*), 100); 100*7dd7cddfSDavid du Colombier proccreate(timerproc, nil, STACK); 101*7dd7cddfSDavid du Colombier } 102*7dd7cddfSDavid du Colombier 103*7dd7cddfSDavid du Colombier /* 104*7dd7cddfSDavid du Colombier * timeralloc() and timerfree() don't lock, so can only be 105*7dd7cddfSDavid du Colombier * called from the main proc. 106*7dd7cddfSDavid du Colombier */ 107*7dd7cddfSDavid du Colombier 108*7dd7cddfSDavid du Colombier Timer* 109*7dd7cddfSDavid du Colombier timerstart(int dt) 110*7dd7cddfSDavid du Colombier { 111*7dd7cddfSDavid du Colombier Timer *t; 112*7dd7cddfSDavid du Colombier 113*7dd7cddfSDavid du Colombier t = timer; 114*7dd7cddfSDavid du Colombier if(t) 115*7dd7cddfSDavid du Colombier timer = timer->next; 116*7dd7cddfSDavid du Colombier else{ 117*7dd7cddfSDavid du Colombier t = emalloc(sizeof(Timer)); 118*7dd7cddfSDavid du Colombier t->c = chancreate(sizeof(int), 0); 119*7dd7cddfSDavid du Colombier } 120*7dd7cddfSDavid du Colombier t->next = nil; 121*7dd7cddfSDavid du Colombier t->dt = dt; 122*7dd7cddfSDavid du Colombier t->cancel = FALSE; 123*7dd7cddfSDavid du Colombier sendp(ctimer, t); 124*7dd7cddfSDavid du Colombier return t; 125*7dd7cddfSDavid du Colombier } 126