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