1 e830a908 2005-11-06 devnull #include <u.h>
2 e830a908 2005-11-06 devnull #include <libc.h>
3 e830a908 2005-11-06 devnull #include <draw.h>
4 e830a908 2005-11-06 devnull #include <thread.h>
5 e830a908 2005-11-06 devnull #include <cursor.h>
6 e830a908 2005-11-06 devnull #include <mouse.h>
7 e830a908 2005-11-06 devnull #include <keyboard.h>
8 e830a908 2005-11-06 devnull #include <frame.h>
9 e830a908 2005-11-06 devnull #include <fcall.h>
10 e830a908 2005-11-06 devnull #include "dat.h"
11 e830a908 2005-11-06 devnull #include "fns.h"
13 e830a908 2005-11-06 devnull static Channel* ctimer; /* chan(Timer*)[100] */
14 e830a908 2005-11-06 devnull static Timer *timer;
18 e830a908 2005-11-06 devnull msec(void)
20 e830a908 2005-11-06 devnull return nsec()/1000000;
24 e830a908 2005-11-06 devnull timerstop(Timer *t)
26 e830a908 2005-11-06 devnull t->next = timer;
27 e830a908 2005-11-06 devnull timer = t;
31 e830a908 2005-11-06 devnull timercancel(Timer *t)
33 e830a908 2005-11-06 devnull t->cancel = TRUE;
38 e830a908 2005-11-06 devnull timerproc(void *a)
40 e830a908 2005-11-06 devnull int i, nt, na, dt, del;
41 e830a908 2005-11-06 devnull Timer **t, *x;
42 e830a908 2005-11-06 devnull uint old, new;
45 e830a908 2005-11-06 devnull rfork(RFFDG);
46 e830a908 2005-11-06 devnull threadsetname("TIMERPROC");
50 e830a908 2005-11-06 devnull old = msec();
52 e830a908 2005-11-06 devnull sleep(1); /* will sleep minimum incr */
53 e830a908 2005-11-06 devnull new = msec();
54 e830a908 2005-11-06 devnull dt = new-old;
55 e830a908 2005-11-06 devnull old = new;
56 e830a908 2005-11-06 devnull if(dt < 0) /* timer wrapped; go around, losing a tick */
57 e830a908 2005-11-06 devnull continue;
58 e830a908 2005-11-06 devnull for(i=0; i<nt; i++){
59 e830a908 2005-11-06 devnull x = t[i];
60 e830a908 2005-11-06 devnull x->dt -= dt;
62 e830a908 2005-11-06 devnull if(x->cancel){
63 e830a908 2005-11-06 devnull timerstop(x);
65 e830a908 2005-11-06 devnull }else if(x->dt <= 0){
67 e830a908 2005-11-06 devnull * avoid possible deadlock if client is
68 e830a908 2005-11-06 devnull * now sending on ctimer
70 e830a908 2005-11-06 devnull if(nbsendul(x->c, 0) > 0)
74 e830a908 2005-11-06 devnull memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
79 e830a908 2005-11-06 devnull if(nt == 0){
80 e830a908 2005-11-06 devnull x = recvp(ctimer);
82 e830a908 2005-11-06 devnull if(nt == na){
83 e830a908 2005-11-06 devnull na += 10;
84 e830a908 2005-11-06 devnull t = realloc(t, na*sizeof(Timer*));
85 e830a908 2005-11-06 devnull if(t == nil)
88 e830a908 2005-11-06 devnull t[nt++] = x;
89 e830a908 2005-11-06 devnull old = msec();
91 e830a908 2005-11-06 devnull if(nbrecv(ctimer, &x) > 0)
92 e830a908 2005-11-06 devnull goto gotit;
97 e830a908 2005-11-06 devnull timerinit(void)
99 e830a908 2005-11-06 devnull ctimer = chancreate(sizeof(Timer*), 100);
100 e830a908 2005-11-06 devnull proccreate(timerproc, nil, STACK);
104 e830a908 2005-11-06 devnull * timeralloc() and timerfree() don't lock, so can only be
105 e830a908 2005-11-06 devnull * called from the main proc.
109 e830a908 2005-11-06 devnull timerstart(int dt)
111 e830a908 2005-11-06 devnull Timer *t;
113 e830a908 2005-11-06 devnull t = timer;
115 e830a908 2005-11-06 devnull timer = timer->next;
117 e830a908 2005-11-06 devnull t = emalloc(sizeof(Timer));
118 e830a908 2005-11-06 devnull t->c = chancreate(sizeof(int), 0);
120 e830a908 2005-11-06 devnull t->next = nil;
121 e830a908 2005-11-06 devnull t->dt = dt;
122 e830a908 2005-11-06 devnull t->cancel = FALSE;
123 e830a908 2005-11-06 devnull sendp(ctimer, t);
124 e830a908 2005-11-06 devnull return t;