M gnot/fns.h => gnot/fns.h +0 -1
@@ 36,7 36,6 @@ void procrestore(Proc*);
void procsave(Proc*);
void procsetup(Proc*);
void putkmmu(ulong, ulong);
-void restartprint(Alarm*);
void restfpregs(FPsave*);
void screeninit(void);
void screenputc(int);
M gnot/main.c => gnot/main.c +0 -1
@@ 50,7 50,6 @@ main(void)
initseg();
grpinit();
chaninit();
- alarminit();
chandevreset();
streaminit();
/* serviceinit(); /**/
M pc/devuart.c => pc/devuart.c +0 -15
@@ 70,7 70,6 @@ struct Uart
/* stream interface */
Queue *wq; /* write queue */
Rendez r; /* kproc waiting for input */
- Alarm *a; /* alarm for waking the kernel process */
int kstarted; /* kproc started */
/* error statistics */
@@ 401,7 400,6 @@ uartspecial(int port, IOQ *oq, IOQ *iq, int baud)
}
}
-static void uarttimer(Alarm*);
static int uartputc(IOQ *, int);
static void uartstopen(Queue*, Stream*);
static void uartstclose(Queue*);
@@ 416,19 414,6 @@ Qinfo uartinfo =
"uart"
};
-/*
- * create a helper process per port
- */
-static void
-uarttimer(Alarm *a)
-{
- Uart *up = a->arg;
-
- cancel(a);
- up->a = 0;
- wakeup(&up->iq->r);
-}
-
static void
uartstopen(Queue *q, Stream *s)
{
M pc/main.c => pc/main.c +0 -1
@@ 32,7 32,6 @@ main(void)
initseg();
grpinit();
chaninit();
- alarminit();
chandevreset();
streaminit();
swapinit();
M port/alarm.c => port/alarm.c +43 -168
@@ 5,93 5,14 @@
#include "fns.h"
#include "io.h"
-struct {
- Lock;
- 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;
- int s;
-
- if(ms < 0)
- ms = 0;
- a = newalarm();
- a->when = MACHP(0)->ticks+MS2TK(ms);
- a->f = f;
- a->arg = arg;
- s = splhi();
- lock(&alarmalloc);
- pw = 0;
- for(w=alarmalloc.list; w; pw=w, w=w->next){
- if(w->when > a->when)
- break;
- }
- insert(&alarmalloc.list, pw, a);
- unlock(&alarmalloc);
- splx(s);
- return a;
-}
+Rendez alarmr;
+Talarm talarm;
void
-cancel(Alarm *a)
-{
- a->f = 0;
-}
-
-Alarm*
-newalarm(void)
-{
- int i;
- Alarm *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);
- continue;
- }
- a->f = 0;
- a->arg = 0;
- a->busy = 1;
- unlock(a);
- return a;
- }
- panic("newalarm");
- return 0; /* not reached */
-}
-
-/* allocate locks here since you can't allocate them at interrupt time (on the SGI) */
-void
-alarminit(void)
-{
- int i;
-
- alarmalloc.tab = ialloc(conf.nalarm*sizeof(Alarm), 0);
- for(i=0; i<conf.nalarm; i++){
- lock(&alarmalloc.tab[i]);
- unlock(&alarmalloc.tab[i]);
- }
- lock(&alarmalloc);
- unlock(&alarmalloc);
- qlock(&alarms);
- qunlock(&alarms);
-}
-
-#define NA 10 /* alarms per wakeup */
-void
alarmkproc(void *arg)
{
int i, n;
- Alarm *a;
- void (*f)(void*);
- Alarm *alist[NA];
ulong now;
Proc *rp;
int s;
@@ 100,40 21,6 @@ alarmkproc(void *arg)
for(;;){
now = MACHP(0)->ticks;
-
- s = splhi();
- lock(&alarmalloc);
- a = alarmalloc.list;
- if(a){
- for(n=0; a && a->when<=now && n<NA; n++){
- alist[n] = a;
- delete(&alarmalloc.list, 0, a);
- a = alarmalloc.list;
- }
- unlock(&alarmalloc);
- splx(s);
-
- /*
- * 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(&alarmalloc);
- splx(s);
- }
-
qlock(&alarms);
while((rp = alarms.head) && rp->alarm <= now){
if(rp->alarm != 0L){
@@ 151,7 38,7 @@ alarmkproc(void *arg)
}
qunlock(&alarms);
- sleep(&alarmalloc.r, return0, 0);
+ sleep(&alarmr, return0, 0);
}
}
@@ 161,90 48,78 @@ alarmkproc(void *arg)
void
checkalarms(void)
{
- ulong now;
Proc *p;
- Alarm *a;
+ ulong now;
- a = alarmalloc.list;
p = alarms.head;
now = MACHP(0)->ticks;
- if((a && a->when <= now) || (p && p->alarm <= now))
- wakeup(&alarmalloc.r);
+ if(p && p->alarm <= now)
+ wakeup(&alarmr);
+
+ if(talarm.list == 0 || canlock(&talarm) == 0)
+ return;
+
+ for(;;) {
+ p = talarm.list;
+ if(p == 0)
+ break;
+
+ if(p->twhen == 0) {
+ talarm.list = p->tlink;
+ continue;
+ }
+ if(now < p->twhen)
+ break;
+ talarm.list = p->tlink;
+ wakeup(p->trend);
+ }
+
+ unlock(&talarm);
}
ulong
procalarm(ulong time)
{
- Proc **l, *f;
+ Proc **l, *f, *p;
ulong when, old;
- old = TK2MS(u->p->alarm - MACHP(0)->ticks);
- if(time == 0){
- u->p->alarm = 0;
+ p = u->p;
+ old = TK2MS(p->alarm - MACHP(0)->ticks);
+ if(time == 0) {
+ p->alarm = 0;
return old;
}
- when = MS2TK(time);
- when += MACHP(0)->ticks;
+ when = MS2TK(time)+MACHP(0)->ticks;
qlock(&alarms);
l = &alarms.head;
- for(f = *l; f; f = f->palarm){
- if(u->p == f){
+ for(f = *l; f; f = f->palarm) {
+ if(p == f){
*l = f->palarm;
break;
}
l = &f->palarm;
}
- u->p->palarm = 0;
- if(alarms.head){
+ 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;
+ for(f = *l; f; f = f->palarm) {
+ if(f->alarm > when) {
+ p->palarm = f;
+ *l = p;
goto done;
}
l = &f->palarm;
}
- *l = u->p;
+ *l = p;
}
else
- alarms.head = u->p;
+ alarms.head = p;
done:
- u->p->alarm = when;
+ p->alarm = when;
qunlock(&alarms);
return old;
}
-
-/*
- * 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;
-}
-
M port/devcons.c => port/devcons.c +1 -3
@@ 513,10 513,8 @@ consread(Chan *c, void *buf, long n, ulong offset)
do{
lock(&lineq);
ch = getc(&kbdq);
- if(raw){
- unlock(&lineq);
+ if(raw)
goto Default;
- }
switch(ch){
case '\b':
if(lineq.in != lineq.out){
M port/devip.c => port/devip.c +5 -5
@@ 1048,7 1048,7 @@ bsdoput(Queue *q, Block *bp)
}
/* collect into a single block */
- lock(q);
+ qlock(&q->rlock);
if(q->first == 0)
q->first = pullup(bp, blen(bp));
else{
@@ 1058,7 1058,7 @@ bsdoput(Queue *q, Block *bp)
}
bp = q->first;
if(bp == 0){
- unlock(q);
+ qunlock(&q->rlock);
bsdclose(q);
return;
}
@@ 1066,12 1066,12 @@ bsdoput(Queue *q, Block *bp)
/* look for 2 nulls to indicate stderr port and local user */
luser = memchr(bp->rptr, 0, BLEN(bp));
if(luser == 0){
- unlock(q);
+ qunlock(&q->rlock);
return;
}
luser++;
if(memchr(luser, 0, bp->wptr - luser) == 0){
- unlock(q);
+ qunlock(&q->rlock);
return;
}
@@ 1084,5 1084,5 @@ bsdoput(Queue *q, Block *bp)
q->first = 0;
bp->flags |= S_DELIM;
PUTNEXT(q, bp);
- unlock(q);
+ qunlock(&q->rlock);
}
M port/devscc.c => port/devscc.c +0 -1
@@ 103,7 103,6 @@ struct SCC
/* stream interface */
Queue *wq; /* write queue */
Rendez r; /* kproc waiting for input */
- Alarm *a; /* alarm for waking the kernel process */
int kstarted; /* kproc started */
/* idiot flow control */
M port/fault.c => port/fault.c +1 -0
@@ 17,6 17,7 @@ fault(ulong addr, int read)
sps = u->p->psstate;
u->p->psstate = "Fault";
+ spllo();
m->pfault++;
for(;;) {
M port/pgrp.c => port/pgrp.c +2 -3
@@ 199,9 199,8 @@ resrcwait(char *reason)
}
if(u == 0)
panic("resrcwait");
- u->p->state = Wakeme;
- alarm(1000, wakeme, u->p);
- sched();
+
+ tsleep(&u->p->sleep, return0, 0, 1000);
u->p->psstate = p;
}
M port/portdat.h => port/portdat.h +10 -8
@@ 1,4 1,3 @@
-typedef struct Alarm Alarm;
typedef struct Alarms Alarms;
typedef struct Block Block;
typedef struct Blist Blist;
@@ 35,6 34,7 @@ typedef struct Rendez Rendez;
typedef struct RWlock RWlock;
typedef struct Segment Segment;
typedef struct Stream Stream;
+typedef struct Talarm Talarm;
typedef struct Waitq Waitq;
typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
@@ 71,14 71,10 @@ struct RWlock
int readers; /* Count of readers in lock */
};
-struct Alarm
+struct Talarm
{
- List;
Lock;
- int busy;
- ulong when; /* may underflow in clock(); must be signed */
- void (*f)(void*);
- void *arg;
+ Proc *list;
};
struct Alarms
@@ 550,7 546,7 @@ struct Proc
ulong pc; /* DEBUG only */
Rendez *r; /* rendezvous point slept on */
- Rendez sleep; /* place for tsleep/syssleep/debug */
+ Rendez sleep; /* place for syssleep/debug */
int notepending; /* note issued but not acted on */
int kp; /* true if a kernel process */
Proc *palarm; /* Next alarm time */
@@ 561,6 557,11 @@ struct Proc
ulong rendtag; /* Tag for rendezvous */
ulong rendval; /* Value for rendezvous */
Proc *rendhash; /* Hash list for tag values */
+
+ ulong twhen;
+ Rendez *trend;
+ Proc *tlink;
+
/*
* machine specific MMU goo
*/
@@ 696,6 697,7 @@ extern int nrdy;
extern char sysname[NAMELEN];
extern int cpuserver;
extern Ref noteidalloc;
+extern Talarm talarm;
#define CHDIR 0x80000000L
#define CHAPPEND 0x40000000L
M port/portfns.h => port/portfns.h +0 -7
@@ 1,5 1,3 @@
-Alarm* alarm(int, void (*)(Alarm*), void*);
-void alarminit(void);
void alarmkproc(void*);
Block* allocb(ulong);
int anyready(void);
@@ 9,7 7,6 @@ int blen(Block *);
int bround(Block *, int);
void buzz(int, int);
void cachepage(Page*, Image*);
-void cancel(Alarm*);
int cangetc(void*);
int canlock(Lock*);
int canpage(Proc*);
@@ 73,7 70,6 @@ void firmware(void);
int fixfault(Segment*, ulong, int, int);
void flowctl(Queue*, Block*);
void flushmmu(void);
-void freealarm(Alarm*);
void freeb(Block*);
int freebroken(void);
void freechan(Chan*);
@@ 133,7 129,6 @@ long netread(Chan*, void*, long, ulong, Network*);
void netstat(Chan*, char*, Network*);
int netwalk(Chan*, char*, Network*);
void netwstat(Chan*, char*, Network*);
-Alarm* newalarm(void);
Chan* newchan(void);
Egrp* newegrp(void);
Fgrp* newfgrp(void);
@@ 236,7 231,6 @@ void swapinit(void);
long syscall(Ureg*);
void tcpinit(void);
void tsleep(Rendez*, int (*)(void*), void*, int);
-void twakeme(Alarm*);
void uncachepage(Page*);
long unionread(Chan*, void*, long);
void unlock(Lock*);
@@ 246,7 240,6 @@ void userinit(void);
ulong userpc(void);
void validaddr(ulong, ulong, int);
void* vmemchr(void*, int, int);
-void wakeme(Alarm*);
void wakeup(Rendez*);
void rlock(RWlock*);
void runlock(RWlock*);
M port/proc.c => port/proc.c +22 -36
@@ 317,29 317,32 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
}
void
-tsleep(Rendez *r, int (*f)(void*), void *arg, int ms)
+tsleep(Rendez *r, int (*fn)(void*), void *arg, int ms)
{
- Alarm *a;
- Proc *p;
- int s;
+ ulong when;
+ Proc *p, *f, **l, **i;
p = u->p;
- sleep1(r, f, arg);
- if(p->notepending == 0){
- a = alarm(ms, twakeme, r);
- sched(); /* notepending may go true while asleep */
- cancel(a);
- }
- if(p->notepending){
- p->notepending = 0;
- s = splhi();
- lock(r);
- if(r->p == p)
- r->p = 0;
- unlock(r);
- splx(s);
- error(Eintr);
+ when = MS2TK(ms)+MACHP(0)->ticks;
+ i = &talarm.list;
+
+ lock(&talarm);
+ l = &talarm.list;
+ for(f = talarm.list; f; f = f->tlink) {
+ if(f == p)
+ *l = p->tlink;
+ if(f->twhen && f->twhen < when)
+ i = &f->tlink;
+ l = &f->tlink;
}
+ p->trend = r;
+ p->twhen = when;
+ p->tlink = *i;
+ *i = p;
+ unlock(&talarm);
+
+ sleep(r, fn, arg);
+ p->twhen = 0;
}
void
@@ 356,29 359,12 @@ wakeup(Rendez *r)
if(p->state != Wakeme)
panic("wakeup: state");
p->r = 0;
-if((p->sched.pc&KZERO) != KZERO){
- spllo();
- panic("wakeup");
-}
ready(p);
}
unlock(r);
splx(s);
}
-void
-wakeme(Alarm *a)
-{
- ready((Proc*)(a->arg));
- cancel(a);
-}
-
-void
-twakeme(Alarm *a)
-{
- wakeup((Rendez*)(a->arg));
-}
-
int
postnote(Proc *p, int dolock, char *n, int flag)
{
M port/taslock.c => port/taslock.c +11 -6
@@ 5,6 5,9 @@
#include "fns.h"
#include "../port/error.h"
+ulong spinner;
+ulong spinpc;
+
void
lock(Lock *l)
{
@@ 13,10 16,12 @@ lock(Lock *l)
ulong pc;
pc = getcallerpc(((uchar*)&l) - sizeof(l));
-if(l == 0){
-print("pc= %lux", pc);
-for(;;);
-}
+ if (tas(&ll->key) == 0){
+ if(u)
+ u->p->hasspin = 1;
+ ll->pc = pc;
+ return;
+ }
for(i = 0; i < 1000000; i++){
if (tas(&ll->key) == 0){
if(u)
@@ 24,8 29,8 @@ for(;;);
ll->pc = pc;
return;
}
- if(u && u->p->state == Running)
- sched();
+spinner++;
+spinpc = pc;
}
i = l->key;
l->key = 0;
M power/main.c => power/main.c +6 -10
@@ 56,7 56,6 @@ main(void)
grpinit();
chaninit();
clockinit();
- alarminit();
ioboardinit();
chandevreset();
streaminit();
@@ 600,7 599,7 @@ confinit(void)
* we do this because the arguments are in memory that may be allocated
* to processes or kernel buffers.
*/
-#define SYSENV "netaddr="
+#define IPADDRENV "netaddr="
void
arginit(void)
{
@@ 614,16 613,13 @@ arginit(void)
/*
* get the system name from the environment
*/
- if(*sysname == 0){
- for(argv = _env; *argv; argv++){
- if(strncmp(*argv, SYSENV, sizeof(SYSENV)-1)==0){
- strcpy(sysname, (*argv) + sizeof(SYSENV)-1);
- break;
- }
+ strcpy(envbuf, IPADDRENV);
+ for(argv = _env; *argv; argv++){
+ if(strncmp(*argv, IPADDRENV, sizeof(IPADDRENV)-1)==0){
+ strcat(envbuf, (*argv) + sizeof(IPADDRENV)-1);
+ break;
}
}
- strcpy(envbuf, SYSENV);
- strcat(envbuf, sysname);
env[0] = envbuf;
env[1] = 0;
M ss/fns.h => ss/fns.h +0 -1
@@ 55,7 55,6 @@ void putwD(ulong, ulong);
void putwE16(ulong, ulong);
void putwE(ulong, ulong);
void systemreset(void);
-void restartprint(Alarm*);
void restfpregs(FPsave*);
void screeninit(void);
void screenputc(int);
M ss/main.c => ss/main.c +0 -1
@@ 36,7 36,6 @@ main(void)
initseg();
grpinit();
chaninit();
- alarminit();
chandevreset();
streaminit();
pageinit();