M gnot/trap.c => gnot/trap.c +2 -2
@@ 211,7 211,7 @@ typedef long Syscall(ulong*);
Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted;
+Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
Syscall *systab[]={
sysr1,
@@ 220,7 220,7 @@ Syscall *systab[]={
syschdir,
sysclose,
sysdup,
- sysdeath,
+ sysalarm,
sysexec,
sysexits,
sysfork,
M port/alarm.c => port/alarm.c +67 -0
@@ 6,6 6,7 @@
#include "io.h"
Alarm *alarmtab;
+Alarms alarms;
Alarm*
alarm(int ms, void (*f)(Alarm*), void *arg)
@@ 82,6 83,8 @@ checkalarms(void)
Alarm *a;
void (*f)(void*);
Alarm *alist[NA];
+ ulong now;
+ Proc *rp;
if(canlock(&m->alarmlock)){
a = m->alarm;
@@ 105,4 108,68 @@ checkalarms(void)
} else
unlock(&m->alarmlock);
}
+
+ if(m == MACHP(0) && canqlock(&alarms)) {
+ now = MACHP(0)->ticks;
+ while((rp = alarms.head) && rp->alarm <= now) {
+ if(rp->alarm != 0L) {
+ if(canlock(&rp->debug)) {
+ postnote(rp, 0, "alarm", NUser);
+ unlock(&rp->debug);
+ rp->alarm = 0L;
+ }
+ else
+ break;
+ }
+ alarms.head = rp->palarm;
+ }
+ }
+ qunlock(&alarms);
+}
+
+ulong
+procalarm(ulong time)
+{
+ Proc **l, *f;
+ ulong when, old;
+
+ when = MS2TK(time);
+ old = u->p->alarm - MACHP(0)->ticks;
+ if(when == 0) {
+ u->p->alarm = 0;
+ return TK2MS(old);
+ }
+ else
+ when += MACHP(0)->ticks;
+
+ qlock(&alarms);
+ l = &alarms.head;
+ for(f = *l; f; f = f->palarm) {
+ if(u->p == f) {
+ *l = f->palarm;
+ break;
+ }
+ l = &f->palarm;
+ }
+
+ u->p->palarm = 0;
+ if(alarms.head) {
+ l = &alarms.head;
+ for(f = *l; f; f = f->palarm) {
+ if(f->alarm > when) {
+ u->p->palarm = f;
+ *l = u->p;
+ goto done;
+ }
+ l = &f->palarm;
+ }
+ *l = u->p;
+ }
+ else
+ alarms.head = u->p;
+done:
+ u->p->alarm = when;
+ qunlock(&alarms);
+
+ return TK2MS(old);
}
M port/portdat.h => port/portdat.h +10 -0
@@ 1,4 1,5 @@
typedef struct Alarm Alarm;
+typedef struct Alarms Alarms;
typedef struct Block Block;
typedef struct Blist Blist;
typedef struct Chan Chan;
@@ 62,6 63,12 @@ struct Alarm
void *arg;
};
+struct Alarms
+{
+ QLock;
+ Proc *head;
+};
+
/* Block.flags */
#define S_DELIM 0x80
#define S_CLASS 0x07
@@ 347,6 354,9 @@ struct Proc
int wokeup; /* whether sleep was interrupted */
ulong pc; /* DEBUG only */
int kp; /* true if a kernel process */
+ Proc *palarm; /* Next alarm time */
+ ulong alarm; /* Time of call */
+
/*
* machine specific MMU goo
*/
M port/portfns.h => port/portfns.h +1 -0
@@ 107,6 107,7 @@ Pgrp* pgrptab(int);
int postnote(Proc*, int, char*, int);
int pprint(char*, ...);
void printslave(void);
+ulong procalarm(ulong);
void procinit0(void);
Proc* proctab(int);
Block* pullup(Block *, int);
M port/proc.c => port/proc.c +1 -0
@@ 441,6 441,7 @@ pexit(char *s, int freemem)
else
msg[0] = 0;
c = u->p;
+ c->alarm = 0;
mypid = c->pid;
if(freemem){
freesegs(-1);
M port/sysproc.c => port/sysproc.c +5 -0
@@ 407,6 407,11 @@ syssleep(ulong *arg)
return 0;
}
+long
+sysalarm(ulong *arg)
+{
+ return procalarm(arg[0]);
+}
long
sysexits(ulong *arg)
M power/trap.c => power/trap.c +2 -2
@@ 437,7 437,7 @@ Syscall sysbind, sysbrk_, syschdir, sysclose, syscreate, sysdeath;
Syscall sysdup, syserrstr, sysexec, sysexits, sysfork, sysforkpgrp;
Syscall sysfstat, sysfwstat, sysgetpid, sysmount, sysnoted;
Syscall sysnotify, sysopen, syspipe, sysr1, sysread, sysremove, sysseek;
-Syscall syssleep, sysstat, syswait, syswrite, syswstat;
+Syscall syssleep, sysstat, syswait, syswrite, syswstat, sysalarm;
Syscall *systab[]={
[SYSR1] sysr1,
@@ 446,7 446,7 @@ Syscall *systab[]={
[CHDIR] syschdir,
[CLOSE] sysclose,
[DUP] sysdup,
- [___ERRSTR___] sysdeath,
+ [ALARM] sysalarm,
[EXEC] sysexec,
[EXITS] sysexits,
[FORK] sysfork,
M ss/trap.c => ss/trap.c +2 -2
@@ 270,7 270,7 @@ typedef long Syscall(ulong*);
Syscall sysr1, sysfork, sysexec, sysgetpid, syssleep, sysexits, sysdeath, syswait;
Syscall sysopen, sysclose, sysread, syswrite, sysseek, syserrstr, sysaccess, sysstat, sysfstat;
Syscall sysdup, syschdir, sysforkpgrp, sysbind, sysmount, syspipe, syscreate;
-Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted;
+Syscall sysbrk_, sysremove, syswstat, sysfwstat, sysnotify, sysnoted, sysalarm;
Syscall *systab[]={
sysr1,
@@ 279,7 279,7 @@ Syscall *systab[]={
syschdir,
sysclose,
sysdup,
- sysdeath,
+ sysalarm,
sysexec,
sysexits,
sysfork,