1 b3994ec5 2003-12-11 devnull #include <u.h>
2 b3994ec5 2003-12-11 devnull #include <libc.h>
3 b3994ec5 2003-12-11 devnull #include <draw.h>
4 b3994ec5 2003-12-11 devnull #include <thread.h>
5 b3994ec5 2003-12-11 devnull #include <cursor.h>
6 b3994ec5 2003-12-11 devnull #include <mouse.h>
7 b3994ec5 2003-12-11 devnull #include <keyboard.h>
8 b3994ec5 2003-12-11 devnull #include <frame.h>
9 b3994ec5 2003-12-11 devnull #include <fcall.h>
10 b3994ec5 2003-12-11 devnull #include <plumb.h>
11 b3994ec5 2003-12-11 devnull #include "dat.h"
12 b3994ec5 2003-12-11 devnull #include "fns.h"
14 b3994ec5 2003-12-11 devnull static Channel* ctimer; /* chan(Timer*)[100] */
15 b3994ec5 2003-12-11 devnull static Timer *timer;
19 b3994ec5 2003-12-11 devnull msec(void)
21 b3994ec5 2003-12-11 devnull return nsec()/1000000;
25 b3994ec5 2003-12-11 devnull timerstop(Timer *t)
27 b3994ec5 2003-12-11 devnull t->next = timer;
28 b3994ec5 2003-12-11 devnull timer = t;
32 b3994ec5 2003-12-11 devnull timercancel(Timer *t)
34 b3994ec5 2003-12-11 devnull t->cancel = TRUE;
39 b3994ec5 2003-12-11 devnull timerproc(void *v)
41 b3994ec5 2003-12-11 devnull int i, nt, na, dt, del;
42 b3994ec5 2003-12-11 devnull Timer **t, *x;
43 b3994ec5 2003-12-11 devnull uint old, new;
46 b3994ec5 2003-12-11 devnull threadsetname("timerproc");
47 b3994ec5 2003-12-11 devnull rfork(RFFDG);
51 b3994ec5 2003-12-11 devnull old = msec();
53 5a8e63b2 2004-02-29 devnull threadsleep(1); /* will sleep minimum incr */
54 b3994ec5 2003-12-11 devnull new = msec();
55 b3994ec5 2003-12-11 devnull dt = new-old;
56 b3994ec5 2003-12-11 devnull old = new;
57 b3994ec5 2003-12-11 devnull if(dt < 0) /* timer wrapped; go around, losing a tick */
58 b3994ec5 2003-12-11 devnull continue;
59 b3994ec5 2003-12-11 devnull for(i=0; i<nt; i++){
60 b3994ec5 2003-12-11 devnull x = t[i];
61 b3994ec5 2003-12-11 devnull x->dt -= dt;
62 b3994ec5 2003-12-11 devnull del = FALSE;
63 b3994ec5 2003-12-11 devnull if(x->cancel){
64 b3994ec5 2003-12-11 devnull timerstop(x);
65 b3994ec5 2003-12-11 devnull del = TRUE;
66 b3994ec5 2003-12-11 devnull }else if(x->dt <= 0){
68 b3994ec5 2003-12-11 devnull * avoid possible deadlock if client is
69 b3994ec5 2003-12-11 devnull * now sending on ctimer
71 b3994ec5 2003-12-11 devnull if(nbsendul(x->c, 0) > 0)
72 b3994ec5 2003-12-11 devnull del = TRUE;
75 b3994ec5 2003-12-11 devnull memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
80 b3994ec5 2003-12-11 devnull if(nt == 0){
81 b3994ec5 2003-12-11 devnull x = recvp(ctimer);
83 b3994ec5 2003-12-11 devnull if(nt == na){
84 b3994ec5 2003-12-11 devnull na += 10;
85 b3994ec5 2003-12-11 devnull t = realloc(t, na*sizeof(Timer*));
86 b3994ec5 2003-12-11 devnull if(t == nil)
87 b3994ec5 2003-12-11 devnull error("timer realloc failed");
89 b3994ec5 2003-12-11 devnull t[nt++] = x;
90 b3994ec5 2003-12-11 devnull old = msec();
92 b3994ec5 2003-12-11 devnull if(nbrecv(ctimer, &x) > 0)
93 b3994ec5 2003-12-11 devnull goto gotit;
98 b3994ec5 2003-12-11 devnull timerinit(void)
100 b3994ec5 2003-12-11 devnull ctimer = chancreate(sizeof(Timer*), 100);
101 5a8e63b2 2004-02-29 devnull threadcreate(timerproc, nil, STACK);
105 b3994ec5 2003-12-11 devnull timerstart(int dt)
107 b3994ec5 2003-12-11 devnull Timer *t;
109 b3994ec5 2003-12-11 devnull t = timer;
111 b3994ec5 2003-12-11 devnull timer = timer->next;
113 b3994ec5 2003-12-11 devnull t = emalloc(sizeof(Timer));
114 b3994ec5 2003-12-11 devnull t->c = chancreate(sizeof(int), 0);
116 b3994ec5 2003-12-11 devnull t->next = nil;
117 b3994ec5 2003-12-11 devnull t->dt = dt;
118 b3994ec5 2003-12-11 devnull t->cancel = FALSE;
119 b3994ec5 2003-12-11 devnull sendp(ctimer, t);
120 b3994ec5 2003-12-11 devnull return t;