M gnot/main.c => gnot/main.c +4 -2
@@ 135,11 135,13 @@ init0(void)
u->p->state = Running;
u->p->mach = m;
spllo();
-
- chandevinit();
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
+
+ kproc("alarm", alarmkproc, 0);
+ chandevinit();
+
if(!waserror()){
ksetterm("at&t %s");
ksetenv("cputype", "68020");
M pc/devhard.c => pc/devhard.c +7 -14
@@ 27,9 27,7 @@ enum
Pstatus= 7, /* status port (read) */
Sbusy= (1<<7),
Sready= (1<<6),
- Sdwf= (1<<5),
Sdrq= (1<<3),
- Scorr= (1<<2),
Serr= (1<<0),
Pcmd= 7, /* cmd port (write) */
@@ 523,16 521,16 @@ retry:
len = pp->end - lblk;
cp->nsecs = len;
- cp->cmd = cmd;
- cp->dp = dp;
+ cmdreadywait(cp);
/*
* start the transfer
*/
+ cp->cmd = cmd;
+ cp->dp = dp;
cp->status = 0;
- cmdreadywait(cp);
- outb(cp->pbase+Pcount, cp->nsecs);
+ outb(cp->pbase+Pcount, cp->nsecs-cp->sofar);
outb(cp->pbase+Psector, sec);
outb(cp->pbase+Pdh, 0x20 | head);
outb(cp->pbase+Pcyllsb, cyl);
@@ 545,7 543,6 @@ retry:
if(++loop > 10000)
panic("hardxfer");
outss(cp->pbase+Pdata, cp->buf, dp->bytes/2);
- cp->nsecs--;
}
sleep(&cp->r, cmddone, cp);
@@ 776,8 773,6 @@ hardintr(Ureg *ur)
cp->cmd, inb(cp->pbase+Pstatus));
panic("hardintr: wait busy");
}
- if(cp->status & (Sdwf|Scorr))
- print("hardintr: cmd=#%lux, status=#%lux\n", cp->cmd, cp->status);
switch(cp->cmd){
case Cwrite:
if(cp->status & Serr){
@@ 788,7 783,7 @@ hardintr(Ureg *ur)
return;
}
cp->sofar++;
- if(cp->nsecs){
+ if(cp->sofar < cp->nsecs){
loop = 0;
while((inb(cp->pbase+Pstatus) & Sdrq) == 0)
if(++loop > 10000) {
@@ 798,8 793,7 @@ hardintr(Ureg *ur)
}
outss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes],
dp->bytes/2);
- cp->nsecs--;
- } else {
+ } else{
cp->lastcmd = cp->cmd;
cp->cmd = 0;
wakeup(&cp->r);
@@ 831,8 825,7 @@ hardintr(Ureg *ur)
inss(cp->pbase+Pdata, &cp->buf[cp->sofar*dp->bytes],
dp->bytes/2);
cp->sofar++;
- cp->nsecs--;
- if(cp->nsecs == 0){
+ if(cp->sofar >= cp->nsecs){
cp->lastcmd = cp->cmd;
if (cp->cmd == Cread)
cp->cmd = 0;
M pc/main.c => pc/main.c +1 -0
@@ 86,6 86,7 @@ init0(void)
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
+ kproc("alarm", alarmkproc, 0);
chandevinit();
if(!waserror()){
M port/alarm.c => port/alarm.c +84 -46
@@ 5,34 5,34 @@
#include "fns.h"
#include "io.h"
-Alarm *alarmtab;
+struct {
+ QLock;
+ Alarm *tab; /* table of all alarm structures */
+ void *list; /* busy alarms */
+ Rendez r;
+} alarmalloc;
+
Alarms alarms;
Alarm*
alarm(int ms, void (*f)(Alarm*), void *arg)
{
Alarm *a, *w, *pw;
- ulong s;
+
if(ms < 0)
ms = 0;
a = newalarm();
- a->dt = MS2TK(ms);
+ a->when = MACHP(0)->ticks+MS2TK(ms);
a->f = f;
a->arg = arg;
- s = splhi();
- lock(&m->alarmlock);
+ qlock(&alarmalloc);
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;
+ for(w=alarmalloc.list; w; pw=w, w=w->next){
+ if(w->when > a->when)
+ break;
}
- insert(&m->alarm, pw, a);
- unlock(&m->alarmlock);
- splx(s);
+ insert(&alarmalloc.list, pw, a);
+ qunlock(&alarmalloc);
return a;
}
@@ 48,7 48,7 @@ newalarm(void)
int i;
Alarm *a;
- for(i=0,a=alarmtab; i<conf.nalarm; i++,a++)
+ for(i=0,a=alarmalloc.tab; i<conf.nalarm; i++,a++)
if(a->busy==0 && a->f==0 && canlock(a)){
if(a->busy){
unlock(a);
@@ 61,6 61,7 @@ newalarm(void)
return a;
}
panic("newalarm");
+ return 0; /* not reached */
}
/* allocate locks here since you can't allocate them at interrupt time (on the SGI) */
@@ 69,18 70,20 @@ alarminit(void)
{
int i;
- alarmtab = ialloc(conf.nalarm*sizeof(Alarm), 0);
+ alarmalloc.tab = ialloc(conf.nalarm*sizeof(Alarm), 0);
for(i=0; i<conf.nalarm; i++){
- lock(&alarmtab[i]);
- unlock(&alarmtab[i]);
+ lock(&alarmalloc.tab[i]);
+ unlock(&alarmalloc.tab[i]);
}
- lock(&alarms);
- unlock(&alarms);
+ qlock(&alarmalloc);
+ qunlock(&alarmalloc);
+ qlock(&alarms);
+ qunlock(&alarms);
}
-#define NA 10 /* alarms per clock tick */
+#define NA 10 /* alarms per wakeup */
void
-checkalarms(void)
+alarmkproc(void *arg)
{
int i, n;
Alarm *a;
@@ 89,35 92,48 @@ checkalarms(void)
ulong now;
Proc *rp;
- if(canlock(&m->alarmlock)){
- a = m->alarm;
+ USED(arg);
+
+ for(;;){
+ now = MACHP(0)->ticks;
+
+ qlock(&alarmalloc);
+ a = alarmalloc.list;
if(a){
- for(n=0; a && a->dt<=0 && n<NA; n++){
+ for(n=0; a && a->when<=now && n<NA; n++){
alist[n] = a;
- delete(&m->alarm, 0, a);
- a = m->alarm;
+ delete(&alarmalloc.list, 0, a);
+ a = alarmalloc.list;
}
- if(a)
- a->dt--;
- unlock(&m->alarmlock);
-
- /* execute alarm functions outside the lock */
- for(i = 0; i < n; i++){
- f = alist[i]->f; /* avoid race with cancel */
- if(f)
- (*f)(alist[i]);
- alist[i]->busy = 0;
+ qunlock(&alarmalloc);
+
+ /*
+ * execute alarm functions outside the lock since they
+ * might call alarm().
+ */
+ f = 0;
+ if(waserror()){
+ print("alarm func %lux caused error %s\n", f, u->error);
+ } else {
+ for(i = 0; i < n; i++){
+ f = alist[i]->f; /* avoid race with cancel */
+ if(f)
+ (*f)(alist[i]);
+ alist[i]->busy = 0;
+ }
+ poperror();
}
}else
- unlock(&m->alarmlock);
- }
+ qunlock(&alarmalloc);
- if(m == MACHP(0) && canlock(&alarms)){
- now = MACHP(0)->ticks;
+ qlock(&alarms);
while((rp = alarms.head) && rp->alarm <= now){
if(rp->alarm != 0L){
if(canqlock(&rp->debug)){
- postnote(rp, 0, "alarm", NUser);
+ if(!waserror()){
+ postnote(rp, 0, "alarm", NUser);
+ poperror();
+ }
qunlock(&rp->debug);
rp->alarm = 0L;
}else
@@ 125,10 141,32 @@ checkalarms(void)
}
alarms.head = rp->palarm;
}
- unlock(&alarms);
+ qunlock(&alarms);
+
+ sleep(&alarmalloc.r, return0, 0);
}
}
+/*
+ * called every clock tick
+ */
+void
+checkalarms(void)
+{
+ ulong now;
+ Proc *p;
+ Alarm *a;
+
+ if(m != MACHP(0))
+ return;
+ a = alarmalloc.list;
+ p = alarms.head;
+ now = MACHP(0)->ticks;
+
+ if((a && a->when <= now) || (p && p->alarm <= now))
+ wakeup(&alarmalloc.r);
+}
+
ulong
procalarm(ulong time)
{
@@ 143,7 181,7 @@ procalarm(ulong time)
when = MS2TK(time);
when += MACHP(0)->ticks;
- lock(&alarms);
+ qlock(&alarms);
l = &alarms.head;
for(f = *l; f; f = f->palarm){
if(u->p == f){
@@ 170,7 208,7 @@ procalarm(ulong time)
alarms.head = u->p;
done:
u->p->alarm = when;
- unlock(&alarms);
+ qunlock(&alarms);
return old;
}
M port/portdat.h => port/portdat.h +2 -2
@@ 76,14 76,14 @@ struct Alarm
List;
Lock;
int busy;
- long dt; /* may underflow in clock(); must be signed */
+ ulong when; /* may underflow in clock(); must be signed */
void (*f)(void*);
void *arg;
};
struct Alarms
{
- Lock;
+ QLock;
Proc *head;
};
M port/portfns.h => port/portfns.h +1 -0
@@ 1,5 1,6 @@
Alarm* alarm(int, void (*)(Alarm*), void*);
void alarminit(void);
+void alarmkproc(void*);
Block* allocb(ulong);
int anyready(void);
void append(List**, List*);
M power/devduart.c => power/devduart.c +1 -1
@@ 232,7 232,7 @@ duartbaud(Duartport *dp, int b)
x = BD300;
break;
default:
- error(Ebadarg);
+ return;
}
if(x & 0x0100)
dp->duart->ipc_acr = duartacr |= 0x80;
M power/main.c => power/main.c +1 -0
@@ 218,6 218,7 @@ init0(void)
*/
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
+ kproc("alarm", alarmkproc, 0);
chandevinit();
if(!waserror()){
M ss/main.c => ss/main.c +3 -2
@@ 103,12 103,13 @@ init0(void)
u->p->state = Running;
u->p->mach = m;
spllo();
-
- chandevinit();
u->slash = (*devtab[0].attach)(0);
u->dot = clone(u->slash, 0);
+ kproc("alarm", alarmkproc, 0);
+ chandevinit();
+
if(!waserror()){
ksetterm("sun %s");
ksetenv("cputype", "sparc");