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