summaryrefslogtreecommitdiff
path: root/sys/src/boot/pc/alarm.c
diff options
context:
space:
mode:
authorTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
committerTaru Karttunen <taruti@taruti.net>2011-03-30 15:46:40 +0300
commite5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch)
treed8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/boot/pc/alarm.c
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/boot/pc/alarm.c')
-rwxr-xr-xsys/src/boot/pc/alarm.c124
1 files changed, 124 insertions, 0 deletions
diff --git a/sys/src/boot/pc/alarm.c b/sys/src/boot/pc/alarm.c
new file mode 100755
index 000000000..f07d038b7
--- /dev/null
+++ b/sys/src/boot/pc/alarm.c
@@ -0,0 +1,124 @@
+#include "u.h"
+#include "lib.h"
+#include "mem.h"
+#include "dat.h"
+#include "fns.h"
+#include "io.h"
+
+#define NA 10 /* max. alarms per clock tick */
+#define MAXALARM (3 * NA)
+
+Alarm alarmtab[MAXALARM];
+
+/*
+ * Insert new into list after where
+ */
+void
+insert(List **head, List *where, List *new)
+{
+ if(where == 0){
+ new->next = *head;
+ *head = new;
+ }else{
+ new->next = where->next;
+ where->next = new;
+ }
+
+}
+
+/*
+ * Delete old from list. where->next is known to be old.
+ */
+void
+delete(List **head, List *where, List *old)
+{
+ if(where == 0){
+ *head = old->next;
+ return;
+ }
+ where->next = old->next;
+}
+
+Alarm*
+newalarm(void)
+{
+ int i;
+ Alarm *a;
+
+ for(i=0,a=alarmtab; i < nelem(alarmtab); i++,a++)
+ if(a->busy==0 && a->f==0){
+ a->f = 0;
+ a->arg = 0;
+ a->busy = 1;
+ return a;
+ }
+ panic("newalarm");
+ return 0; /* not reached */
+}
+
+Alarm*
+alarm(int ms, void (*f)(Alarm*), void *arg)
+{
+ Alarm *a, *w, *pw;
+ ulong s;
+
+ if(ms < 0)
+ ms = 0;
+ s = splhi();
+ a = newalarm();
+ a->dt = MS2TK(ms);
+ a->f = f;
+ a->arg = arg;
+ pw = 0;
+ for(w=m->alarm; w; pw=w, w=w->next){
+ if(w->dt <= a->dt){
+ a->dt -= w->dt;
+ continue;
+ }
+ w->dt -= a->dt;
+ break;
+ }
+ insert(&m->alarm, pw, a);
+ splx(s);
+ return a;
+}
+
+void
+cancel(Alarm *a)
+{
+ a->f = 0;
+}
+
+void
+alarminit(void)
+{
+}
+
+void
+checkalarms(void)
+{
+ int i, n, s;
+ Alarm *a;
+ void (*f)(Alarm*);
+ Alarm *alist[NA];
+
+ s = splhi();
+ a = m->alarm;
+ if(a){
+ for(n=0; a && a->dt<=0 && n<NA; n++){
+ alist[n] = a;
+ delete(&m->alarm, 0, a);
+ a = m->alarm;
+ }
+ if(a)
+ a->dt--;
+
+ for(i = 0; i < n; i++){
+ f = alist[i]->f; /* avoid race with cancel */
+ if(f)
+ (*f)(alist[i]);
+ alist[i]->busy = 0;
+ }
+ }
+ splx(s);
+}