Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

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