xref: /inferno-os/os/boot/puma/alarm.c (revision 74a4d8c26dd3c1e9febcb717cfd6cb6512991a7a)
1*74a4d8c2SCharles.Forsyth #include	"u.h"
2*74a4d8c2SCharles.Forsyth #include	"lib.h"
3*74a4d8c2SCharles.Forsyth #include	"mem.h"
4*74a4d8c2SCharles.Forsyth #include	"dat.h"
5*74a4d8c2SCharles.Forsyth #include	"fns.h"
6*74a4d8c2SCharles.Forsyth #include	"io.h"
7*74a4d8c2SCharles.Forsyth #define	MAXALARM	10
8*74a4d8c2SCharles.Forsyth 
9*74a4d8c2SCharles.Forsyth Alarm	alarmtab[MAXALARM];
10*74a4d8c2SCharles.Forsyth 
11*74a4d8c2SCharles.Forsyth /*
12*74a4d8c2SCharles.Forsyth  * Insert new into list after where
13*74a4d8c2SCharles.Forsyth  */
14*74a4d8c2SCharles.Forsyth void
insert(List ** head,List * where,List * new)15*74a4d8c2SCharles.Forsyth insert(List **head, List *where, List *new)
16*74a4d8c2SCharles.Forsyth {
17*74a4d8c2SCharles.Forsyth 	if(where == 0){
18*74a4d8c2SCharles.Forsyth 		new->next = *head;
19*74a4d8c2SCharles.Forsyth 		*head = new;
20*74a4d8c2SCharles.Forsyth 	}else{
21*74a4d8c2SCharles.Forsyth 		new->next = where->next;
22*74a4d8c2SCharles.Forsyth 		where->next = new;
23*74a4d8c2SCharles.Forsyth 	}
24*74a4d8c2SCharles.Forsyth 
25*74a4d8c2SCharles.Forsyth }
26*74a4d8c2SCharles.Forsyth 
27*74a4d8c2SCharles.Forsyth /*
28*74a4d8c2SCharles.Forsyth  * Delete old from list.  where->next is known to be old.
29*74a4d8c2SCharles.Forsyth  */
30*74a4d8c2SCharles.Forsyth void
delete(List ** head,List * where,List * old)31*74a4d8c2SCharles.Forsyth delete(List **head, List *where, List *old)
32*74a4d8c2SCharles.Forsyth {
33*74a4d8c2SCharles.Forsyth 	if(where == 0){
34*74a4d8c2SCharles.Forsyth 		*head = old->next;
35*74a4d8c2SCharles.Forsyth 		return;
36*74a4d8c2SCharles.Forsyth 	}
37*74a4d8c2SCharles.Forsyth 	where->next = old->next;
38*74a4d8c2SCharles.Forsyth }
39*74a4d8c2SCharles.Forsyth 
40*74a4d8c2SCharles.Forsyth Alarm*
newalarm(void)41*74a4d8c2SCharles.Forsyth newalarm(void)
42*74a4d8c2SCharles.Forsyth {
43*74a4d8c2SCharles.Forsyth 	int i;
44*74a4d8c2SCharles.Forsyth 	Alarm *a;
45*74a4d8c2SCharles.Forsyth 
46*74a4d8c2SCharles.Forsyth 	for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
47*74a4d8c2SCharles.Forsyth 		if(a->busy==0 && a->f==0){
48*74a4d8c2SCharles.Forsyth 			a->f = 0;
49*74a4d8c2SCharles.Forsyth 			a->arg = 0;
50*74a4d8c2SCharles.Forsyth 			a->busy = 1;
51*74a4d8c2SCharles.Forsyth 			return a;
52*74a4d8c2SCharles.Forsyth 		}
53*74a4d8c2SCharles.Forsyth 	panic("newalarm");
54*74a4d8c2SCharles.Forsyth 	return 0;	/* not reached */
55*74a4d8c2SCharles.Forsyth }
56*74a4d8c2SCharles.Forsyth 
57*74a4d8c2SCharles.Forsyth Alarm*
alarm(int ms,void (* f)(Alarm *),void * arg)58*74a4d8c2SCharles.Forsyth alarm(int ms, void (*f)(Alarm*), void *arg)
59*74a4d8c2SCharles.Forsyth {
60*74a4d8c2SCharles.Forsyth 	Alarm *a, *w, *pw;
61*74a4d8c2SCharles.Forsyth 	ulong s;
62*74a4d8c2SCharles.Forsyth 
63*74a4d8c2SCharles.Forsyth 	if(ms < 0)
64*74a4d8c2SCharles.Forsyth 		ms = 0;
65*74a4d8c2SCharles.Forsyth 	s = splhi();
66*74a4d8c2SCharles.Forsyth 	a = newalarm();
67*74a4d8c2SCharles.Forsyth 	a->dt = MS2TK(ms);
68*74a4d8c2SCharles.Forsyth 	a->f = f;
69*74a4d8c2SCharles.Forsyth 	a->arg = arg;
70*74a4d8c2SCharles.Forsyth 	pw = 0;
71*74a4d8c2SCharles.Forsyth 	for(w=m->alarm; w; pw=w, w=w->next){
72*74a4d8c2SCharles.Forsyth 		if(w->dt <= a->dt){
73*74a4d8c2SCharles.Forsyth 			a->dt -= w->dt;
74*74a4d8c2SCharles.Forsyth 			continue;
75*74a4d8c2SCharles.Forsyth 		}
76*74a4d8c2SCharles.Forsyth 		w->dt -= a->dt;
77*74a4d8c2SCharles.Forsyth 		break;
78*74a4d8c2SCharles.Forsyth 	}
79*74a4d8c2SCharles.Forsyth 	insert(&m->alarm, pw, a);
80*74a4d8c2SCharles.Forsyth 	splx(s);
81*74a4d8c2SCharles.Forsyth 	return a;
82*74a4d8c2SCharles.Forsyth }
83*74a4d8c2SCharles.Forsyth 
84*74a4d8c2SCharles.Forsyth void
cancel(Alarm * a)85*74a4d8c2SCharles.Forsyth cancel(Alarm *a)
86*74a4d8c2SCharles.Forsyth {
87*74a4d8c2SCharles.Forsyth 	a->f = 0;
88*74a4d8c2SCharles.Forsyth }
89*74a4d8c2SCharles.Forsyth 
90*74a4d8c2SCharles.Forsyth void
alarminit(void)91*74a4d8c2SCharles.Forsyth alarminit(void)
92*74a4d8c2SCharles.Forsyth {
93*74a4d8c2SCharles.Forsyth }
94*74a4d8c2SCharles.Forsyth 
95*74a4d8c2SCharles.Forsyth #define NA 10		/* alarms per clock tick */
96*74a4d8c2SCharles.Forsyth void
checkalarms(void)97*74a4d8c2SCharles.Forsyth checkalarms(void)
98*74a4d8c2SCharles.Forsyth {
99*74a4d8c2SCharles.Forsyth 	int i, n, s;
100*74a4d8c2SCharles.Forsyth 	Alarm *a;
101*74a4d8c2SCharles.Forsyth 	void (*f)(void*);
102*74a4d8c2SCharles.Forsyth 	Alarm *alist[NA];
103*74a4d8c2SCharles.Forsyth 
104*74a4d8c2SCharles.Forsyth 	s = splhi();
105*74a4d8c2SCharles.Forsyth 	a = m->alarm;
106*74a4d8c2SCharles.Forsyth 	if(a){
107*74a4d8c2SCharles.Forsyth 		for(n=0; a && a->dt<=0 && n<NA; n++){
108*74a4d8c2SCharles.Forsyth 			alist[n] = a;
109*74a4d8c2SCharles.Forsyth 			delete(&m->alarm, 0, a);
110*74a4d8c2SCharles.Forsyth 			a = m->alarm;
111*74a4d8c2SCharles.Forsyth 		}
112*74a4d8c2SCharles.Forsyth 		if(a)
113*74a4d8c2SCharles.Forsyth 			a->dt--;
114*74a4d8c2SCharles.Forsyth 
115*74a4d8c2SCharles.Forsyth 		for(i = 0; i < n; i++){
116*74a4d8c2SCharles.Forsyth 			f = alist[i]->f;	/* avoid race with cancel */
117*74a4d8c2SCharles.Forsyth 			if(f)
118*74a4d8c2SCharles.Forsyth 				(*f)(alist[i]);
119*74a4d8c2SCharles.Forsyth 			alist[i]->busy = 0;
120*74a4d8c2SCharles.Forsyth 		}
121*74a4d8c2SCharles.Forsyth 	}
122*74a4d8c2SCharles.Forsyth 	splx(s);
123*74a4d8c2SCharles.Forsyth }
124