Blame


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"
12 e830a908 2005-11-06 devnull
13 e830a908 2005-11-06 devnull static Channel* ctimer; /* chan(Timer*)[100] */
14 e830a908 2005-11-06 devnull static Timer *timer;
15 e830a908 2005-11-06 devnull
16 e830a908 2005-11-06 devnull static
17 e830a908 2005-11-06 devnull uint
18 e830a908 2005-11-06 devnull msec(void)
19 e830a908 2005-11-06 devnull {
20 e830a908 2005-11-06 devnull return nsec()/1000000;
21 e830a908 2005-11-06 devnull }
22 e830a908 2005-11-06 devnull
23 e830a908 2005-11-06 devnull void
24 e830a908 2005-11-06 devnull timerstop(Timer *t)
25 e830a908 2005-11-06 devnull {
26 e830a908 2005-11-06 devnull t->next = timer;
27 e830a908 2005-11-06 devnull timer = t;
28 e830a908 2005-11-06 devnull }
29 e830a908 2005-11-06 devnull
30 e830a908 2005-11-06 devnull void
31 e830a908 2005-11-06 devnull timercancel(Timer *t)
32 e830a908 2005-11-06 devnull {
33 e830a908 2005-11-06 devnull t->cancel = TRUE;
34 e830a908 2005-11-06 devnull }
35 e830a908 2005-11-06 devnull
36 e830a908 2005-11-06 devnull static
37 e830a908 2005-11-06 devnull void
38 e830a908 2005-11-06 devnull timerproc(void *a)
39 e830a908 2005-11-06 devnull {
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;
43 e830a908 2005-11-06 devnull
44 e830a908 2005-11-06 devnull USED(a);
45 e830a908 2005-11-06 devnull rfork(RFFDG);
46 e830a908 2005-11-06 devnull threadsetname("TIMERPROC");
47 e830a908 2005-11-06 devnull t = nil;
48 e830a908 2005-11-06 devnull na = 0;
49 e830a908 2005-11-06 devnull nt = 0;
50 e830a908 2005-11-06 devnull old = msec();
51 e830a908 2005-11-06 devnull for(;;){
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;
61 e830a908 2005-11-06 devnull del = 0;
62 e830a908 2005-11-06 devnull if(x->cancel){
63 e830a908 2005-11-06 devnull timerstop(x);
64 e830a908 2005-11-06 devnull del = 1;
65 e830a908 2005-11-06 devnull }else if(x->dt <= 0){
66 e830a908 2005-11-06 devnull /*
67 e830a908 2005-11-06 devnull * avoid possible deadlock if client is
68 e830a908 2005-11-06 devnull * now sending on ctimer
69 e830a908 2005-11-06 devnull */
70 e830a908 2005-11-06 devnull if(nbsendul(x->c, 0) > 0)
71 e830a908 2005-11-06 devnull del = 1;
72 e830a908 2005-11-06 devnull }
73 e830a908 2005-11-06 devnull if(del){
74 e830a908 2005-11-06 devnull memmove(&t[i], &t[i+1], (nt-i-1)*sizeof t[0]);
75 e830a908 2005-11-06 devnull --nt;
76 e830a908 2005-11-06 devnull --i;
77 e830a908 2005-11-06 devnull }
78 e830a908 2005-11-06 devnull }
79 e830a908 2005-11-06 devnull if(nt == 0){
80 e830a908 2005-11-06 devnull x = recvp(ctimer);
81 e830a908 2005-11-06 devnull gotit:
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)
86 e830a908 2005-11-06 devnull abort();
87 e830a908 2005-11-06 devnull }
88 e830a908 2005-11-06 devnull t[nt++] = x;
89 e830a908 2005-11-06 devnull old = msec();
90 e830a908 2005-11-06 devnull }
91 e830a908 2005-11-06 devnull if(nbrecv(ctimer, &x) > 0)
92 e830a908 2005-11-06 devnull goto gotit;
93 e830a908 2005-11-06 devnull }
94 e830a908 2005-11-06 devnull }
95 e830a908 2005-11-06 devnull
96 e830a908 2005-11-06 devnull void
97 e830a908 2005-11-06 devnull timerinit(void)
98 e830a908 2005-11-06 devnull {
99 e830a908 2005-11-06 devnull ctimer = chancreate(sizeof(Timer*), 100);
100 e830a908 2005-11-06 devnull proccreate(timerproc, nil, STACK);
101 e830a908 2005-11-06 devnull }
102 e830a908 2005-11-06 devnull
103 e830a908 2005-11-06 devnull /*
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.
106 e830a908 2005-11-06 devnull */
107 e830a908 2005-11-06 devnull
108 e830a908 2005-11-06 devnull Timer*
109 e830a908 2005-11-06 devnull timerstart(int dt)
110 e830a908 2005-11-06 devnull {
111 e830a908 2005-11-06 devnull Timer *t;
112 e830a908 2005-11-06 devnull
113 e830a908 2005-11-06 devnull t = timer;
114 e830a908 2005-11-06 devnull if(t)
115 e830a908 2005-11-06 devnull timer = timer->next;
116 e830a908 2005-11-06 devnull else{
117 e830a908 2005-11-06 devnull t = emalloc(sizeof(Timer));
118 e830a908 2005-11-06 devnull t->c = chancreate(sizeof(int), 0);
119 e830a908 2005-11-06 devnull }
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;
125 e830a908 2005-11-06 devnull }