xref: /inferno-os/os/boot/mpc/alarm.c (revision 7ef44d652ae9e5e1f5b3465d73684e4a54de73c0)
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