From fec5850e4249b1f81830724a442eadc9206a4db0 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Thu, 4 Oct 1990 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1990-10-04 --- gnot/clock.c | 14 +-- gnot/dat.h | 22 +++- gnot/devdk.c | 21 ++-- gnot/fns.h | 4 +- gnot/l.s | 5 + gnot/main.c | 10 +- gnot/mmu.c | 50 +++++++- gnot/proc.c | 305 +++++++++++++++++++++++++++++++----------------- gnot/screen.c | 7 +- gnot/sturp.c | 22 ++-- gnot/sysproc.c | 10 +- port/devdk.c | 18 ++- port/devkprof.c | 10 +- port/devmnt.c | 5 +- port/sturp.c | 41 ++++--- port/sysfile.c | 2 +- power/main.c | 3 +- 17 files changed, 359 insertions(+), 190 deletions(-) diff --git a/gnot/clock.c b/gnot/clock.c index 854be58349d1cfc8d70555f8c7b0a8fe392e259b..70efe4995c04994a8fa9ec5507fcbe517ca1e2f8 100644 --- a/gnot/clock.c +++ b/gnot/clock.c @@ -102,7 +102,8 @@ clock(Ureg *ur) p = m->proc; if(p){ p->pc = ur->pc; - p->time[p->insyscall]++; + if (p->state==Running) + p->time[p->insyscall]++; } if(canlock(&m->alarmlock)){ if(m->alarm){ @@ -127,12 +128,9 @@ clock(Ureg *ur) } kbdclock(); mouseclock(); - if((ur->sr&SPL(7)) == 0){ - spllo(); - if(p && p->state==Running){ - checksched(); - if(u->nnote && (ur->sr&SUPER)==0) - notify(ur); - } + if((ur->sr&SPL(7)) == 0 && p && p->state==Running){ + sched(); + if(u->nnote && (ur->sr&SUPER)==0) + notify(ur); } } diff --git a/gnot/dat.h b/gnot/dat.h index 1fe695070f0589639306c5280a780ac59ed5b214..7e63bd79415a7c1c9fcfc93e3dff97b89e24f58f 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -101,7 +101,7 @@ struct Chan Mount *mnt; /* mount point that derived Chan */ ulong mountid; int fid; /* for devmnt */ - union{ + union { Stream *stream; /* for stream channels */ void *aux; }; @@ -205,9 +205,11 @@ struct KMap struct Mach { int machno; /* physical id of processor */ + ulong splpc; /* pc of last caller to splhi */ int mmask; /* 1<machno */ ulong ticks; /* of the clock since boot time */ Proc *proc; /* current process on this processor */ + Proc *lproc; /* last process on this processor */ Label sched; /* scheduler wakeup */ Lock alarmlock; /* access to alarm list */ void *alarm; /* alarms bound to this clock */ @@ -316,6 +318,7 @@ struct Proc Proc *qnext; /* next process on queue for a QLock */ QLock *qlock; /* address of qlock being queued for DEBUG */ int state; + int spin; /* spinning instead of unscheduled */ Page *upage; /* BUG: should be unlinked from page list */ Seg seg[NSEG]; ulong bssend; /* initial top of bss seg */ @@ -340,6 +343,20 @@ struct Proc Rendez sleep; /* place for tsleep and syssleep */ int wokeup; /* whether sleep was interrupted */ ulong pc; /* DEBUG only */ + int kp; /* true if a kernel process */ +}; + +struct MMU +{ + ulong va; + ulong pa; +}; + +#define NMMU 16 +struct MMUCache +{ + ulong next; + MMU mmu[NMMU]; }; #define NERR 15 @@ -365,6 +382,7 @@ struct User short nnote; short notified; /* sysnoted is due */ int (*notify)(void*, char*); + MMUCache mc; void *ureg; }; @@ -565,3 +583,5 @@ extern Dev devtab[]; extern char devchar[]; extern FPsave initfp; extern Mach mach0; + +extern void (*kprofp)(ulong); diff --git a/gnot/devdk.c b/gnot/devdk.c index 79c0f34aef87b756d7307e21ea40793f3be7dd30..a1d628c6f81830bf1cb3298890d062b07a395a2f 100644 --- a/gnot/devdk.c +++ b/gnot/devdk.c @@ -498,6 +498,14 @@ dkmuxconfig(Dk *dp, Block *bp) dkopen(c, ORDWR); dp->csc = c; + /* + * tell datakit we've rebooted. It should close all channels. + */ + if(dp->restart) { + DPRINT("dkmuxconfig: restart %s\n", dp->name); + dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); + } + /* * start a process to deal with it */ @@ -1100,9 +1108,7 @@ dklisten(Chan *c) n = streamread(dc, dialstr, sizeof(dialstr)-1); DPRINT("returns %d\n", n); if(n <= 0) -{print("bad n\n"); error(0, Eio); -} dialstr[n] = 0; DPRINT("dialstr = %s\n", dialstr); @@ -1112,7 +1118,6 @@ dklisten(Chan *c) n = getfields(dialstr, line, 12, '\n'); if (n < 2) { DPRINT("bad dialstr from dk (1 line)\n"); -print("bad dialstr %d '%s'\n", n, dialstr); error(0, Eio); } @@ -1318,16 +1323,6 @@ dkcsckproc(void *a) dp = (Dk *)a; - /* - * tell datakit we've rebooted. It should close all channels. - */ - if(dp->restart) { - DPRINT("dkcsckproc: restart %s\n", dp->name); - dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); - } - DPRINT("dkcsckproc: closeall %s\n", dp->name); - dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); - /* * loop forever listening */ diff --git a/gnot/fns.h b/gnot/fns.h index fc13fac348fedd2c0ec25cf14953ac9ea3d0c7cc..f458eb5cd46284c42e479d6041ddfb5280caad11 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -81,7 +81,6 @@ void kmapinit(void); KMap *kmap(Page*); int kprint(char*, ...); void kproc(char*, void(*)(void*), void*); -void kproftimer(ulong); void kunmap(KMap*); void lock(Lock*); void lockinit(void); @@ -136,7 +135,7 @@ void qlock(QLock*); void qunlock(QLock*); void restartprint(Alarm*); void restfpregs(FPsave*); -Proc *runproc(void); +void restore(void); void savefpregs(FPsave*); void sched(void); void schedinit(void); @@ -151,6 +150,7 @@ void sleep(Rendez*, int(*)(void*), void*); int splhi(void); int spllo(void); void splx(int); +void spldone(void); Devgen streamgen; void streamclose(Chan*); int streamenter(Stream*); diff --git a/gnot/l.s b/gnot/l.s index c010e18879fbf7df402520b3615f4661a8cbf717..bfbb5af2fa7730352d132ce2d3be6726b807ee06 100644 --- a/gnot/l.s +++ b/gnot/l.s @@ -45,6 +45,8 @@ TEXT touser(SB), $-4 TEXT splhi(SB), $0 + MOVL m(SB), A0 + MOVL (A7), 4(A0) MOVL $0, R0 MOVW SR, R0 MOVW $(SUPER|SPL(7)), SR @@ -63,6 +65,9 @@ TEXT splx(SB), $0 MOVW R0, SR RTS +TEXT spldone(SB), $0 + + RTS TEXT flushcpucache(SB), $0 diff --git a/gnot/main.c b/gnot/main.c index 4498ddafc7d7677942e30b622d10a7891e6a82af..6ff806a9a6ddb6472b368b8a8712ed01cdb80cf4 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -101,11 +101,7 @@ init0(void) { Chan *c; - u->nerrlab = 0; - m->proc = u->p; - u->p->state = Running; - u->p->mach = m; - spllo(); + restore(); chandevinit(); u->slash = (*devtab[0].attach)(0); @@ -139,14 +135,13 @@ userinit(void) p->pgrp = newpgrp(); strcpy(p->text, "*init*"); strcpy(p->pgrp->user, protouser); - p->fpstate = FPinit; /* * Kernel Stack */ p->sched.pc = (ulong)init0; p->sched.sp = USERADDR+BY2PG-20; /* BUG */ - p->sched.sr = SUPER|SPL(7); + p->sched.sr = SUPER|SPL(0); p->upage = newpage(0, 0, USERADDR|(p->pid&0xFFFF)); /* @@ -180,6 +175,7 @@ userinit(void) s->minva = UTZERO; s->maxva = UTZERO+BY2PG; + m->proc = p; ready(p); } diff --git a/gnot/mmu.c b/gnot/mmu.c index 329988e8c210d393904c101550c7e63f0226023b..e1ad023ebe4cc60e37b302d52eec9e095f96c638 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -19,15 +19,37 @@ void mapstack(Proc *p) { ulong tlbvirt, tlbphys; - ulong i; + ulong next; + MMU *mm, *mn, *me; if(p->upage->va != (USERADDR|(p->pid&0xFFFF))) panic("mapstack %d 0x%lux 0x%lux", p->pid, p->upage->pa, p->upage->va); tlbvirt = USERADDR; tlbphys = PPN(p->upage->pa) | PTEVALID | PTEKERNEL; putkmmu(tlbvirt, tlbphys); - flushmmu(); - u = (User*)USERADDR; + + /* + * if not a kernel process and this process was not the + * last process on this machine, flush & preload mmu + */ + if(!p->kp && p!=m->lproc){ + flushmmu(); + + /* + * preload the MMU with the last (up to) NMMU user entries + * previously faulted into it for this process. + */ + mn = &u->mc.mmu[u->mc.next&(NMMU-1)]; + me = &u->mc.mmu[NMMU]; + if(u->mc.next >= NMMU){ + for(mm = mn; mm < me; mm++) + UMAP[mm->va] = mm->pa; + } + for(mm = u->mc.mmu; mm < mn; mm++) + UMAP[mm->va] = mm->pa; + + m->lproc = p; + } } void @@ -45,7 +67,19 @@ putmmu(ulong tlbvirt, ulong tlbphys) if(tlbvirt&KZERO) panic("putmmu"); tlbphys |= VTAG(tlbvirt)<<24; - UMAP[(tlbvirt&0x003FE000L)>>2] = tlbphys; + tlbvirt = (tlbvirt&0x003FE000L)>>2; + if(u){ + MMU *mp; + int s; + + s = splhi(); + mp = &(u->mc.mmu[u->mc.next&(NMMU-1)]); + mp->pa = tlbphys; + mp->va = tlbvirt; + u->mc.next++; + splx(s); + } + UMAP[tlbvirt] = tlbphys; } void @@ -56,6 +90,14 @@ flushmmu(void) *PARAM |= TLBFLUSH_; } +void +clearmmucache(void) +{ + if(u == 0) + panic("flushmmucache"); + u->mc.next = 0; +} + void kmapinit(void) { diff --git a/gnot/proc.c b/gnot/proc.c index 800806ea5ec08adcf33dec33ba27919a502bdc83..9462c7e3c981ebd94dc3c182d29aee41e385b066 100644 --- a/gnot/proc.c +++ b/gnot/proc.c @@ -43,91 +43,206 @@ char *statename[]={ /* BUG: generate automatically */ "Broken", }; +int page_alloc(int); /* !ORIG */ +void page_free(int, int); + /* - * Always splhi()'ed. + * Called as the last routine in main(). Wait for a process on the run queue, grab it, + * and run it. Note that in this routine the interrupts are enabled for the first time. */ void schedinit(void) /* never returns */ { Proc *p; + /* + * At init time: wait for a process on the run queue. + */ + for (;;) { + spllo(); + while (runq.head == 0) + /* idle loop */; + splhi(); + lock(&runq); + if (runq.head != 0) + break; + unlock(&runq); + } + + /* + * Set the u pointer and leave it there. In fact, it might as well be a define. + */ + u = (User *) USERADDR; + + /* + * For later rescheduling. Jumped to by sched() on stack switch. + */ setlabel(&m->sched); - if(u){ - m->proc = 0; - p = u->p; - putkmmu(USERADDR, INVALIDPTE); /* safety first */ - u = 0; - if(p->state == Running) - ready(p); - else if(p->state == Moribund){ - p->pid = 0; - unlock(&p->debug); - p->upage->ref--; - /* procalloc already locked */ - p->qnext = procalloc.free; - procalloc.free = p; - p->upage = 0; - unlock(&procalloc); - p->state = Dead; - } - p->mach = 0; + + /* + * Take a process from the run queue. The run queue is locked here, and guaranteed + * to have a process on it. + */ + p = runq.head; + if ((runq.head = p->rnext) == 0) + runq.tail = 0; + unlock(&runq); + + /* + * Ok, here we go. We have a process and we can start running. + */ + mapstack(p); + gotolabel(&p->sched); +} + +/* + * Complete the restoring of a process after mapstack(). The interrupt level here is low. + * However, since the process is not Running, it cannot be rescheduled at this point. We + * set the process state to Running. If the previous process was dead, clean it up. + */ +void +restore(void) +{ + Proc *p = m->proc; /* previous process */ + + u->p->mach = m; + m->proc = u->p; + u->p->state = Running; + if (p->state == Moribund) { + p->pid = 0; + unlock(&p->debug); /* set in pexit */ + p->upage->ref--; + p->upage = 0; + p->qnext = procalloc.free; + procalloc.free = p; + unlock(&procalloc); /* set in pexit */ + p->state = Dead; } - sched(); } +/* + * Save part of the process state. Note: this is not the counterpart of restore(). + */ +void +save(Balu *balu) +{ + fpsave(&u->fpsave); + if (u->fpsave.type) { + if(u->fpsave.size > sizeof u->fpsave.junk) + panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); + fpregsave(u->fpsave.reg); + u->p->fpstate = FPactive; + m->fpstate = FPdirty; + } + if (BALU->cr0 != 0xFFFFFFFF) /* balu busy */ + memcpy(balu, BALU, sizeof *balu); + else { + balu->cr0 = 0xFFFFFFFF; + BALU->cr0 = 0xFFFFFFFF; + } +} + +/* + * Reschedule the process. We do not know whether the interrupt level is low or high + * here, but we set it to low in any case. If there is no other process to run, and + * this process is Running, return immediately. If this process is blocked, and there + * is no other process to run, keep spinning until either this process or another + * process becomes runnable. If it was this process, we can return immediately. + */ void sched(void) { - Proc *p; - ulong tlbvirt, tlbphys; + Proc *p = u->p; + long initfp; Balu balu; + int saved = 0; - if(u){ - splhi(); + /* + * Record that the process is spinning instead of blocked. Ready() uses this + * information to decide what to do with the process. + */ + p->spin = 1; - fpsave(&u->fpsave); - if(u->fpsave.type){ - if(u->fpsave.size > sizeof u->fpsave.junk) - panic("fpsize %d max %d\n", u->fpsave.size, sizeof u->fpsave.junk); - fpregsave(u->fpsave.reg); - u->p->fpstate = FPactive; - m->fpstate = FPdirty; - } - if(BALU->cr0 != 0xFFFFFFFF) /* balu busy */ - memcpy(&balu, BALU, sizeof balu); - else{ - balu.cr0 = 0xFFFFFFFF; - BALU->cr0 = 0xFFFFFFFF; - } - if(setlabel(&u->p->sched)){ /* woke up */ -if(u->p->mach)panic("mach non zero"); - p = u->p; - p->state = Running; - p->mach = m; - m->proc = p; - if(p->fpstate != m->fpstate){ - if(p->fpstate == FPinit){ - u->p->fpstate = FPinit; - fprestore(&initfp); - m->fpstate = FPinit; - }else{ - fpregrestore(u->fpsave.reg); - fprestore(&u->fpsave); - m->fpstate = FPdirty; - } + /* + * Look for a new process to be run. + */ + for (;;) { + spllo(); + + /* + * Idle loop. Return when this process becomes runnable. If nothing else + * to do, start saving some of the process state. + */ + while (runq.head == 0) + if (p->state == Running) + return; + else if (!saved) { + save(&balu); + saved = 1; } - if(balu.cr0 != 0xFFFFFFFF) /* balu busy */ - memcpy(BALU, &balu, sizeof balu); - spllo(); - return; - } - gotolabel(&m->sched); + + /* + * Disable clock interrupts so that there will be no rescheduling in this + * section (on this machine). If there is still a process on the run + * queue, break out of this loop. + */ + splhi(); + lock(&runq); + if (runq.head != 0) + break; + unlock(&runq); + } + p->spin = 0; + + /* + * The first process on the run queue is the process we are going to run. First + * save our state before we jump to schedinit. If this process was running, put + * it on the run queue. + */ + if (p->state == Running) { + p->state = Ready; + p->rnext = 0; + runq.tail->rnext = p; + runq.tail = p; } + + /* + * Save some process state (if we haven't done that already) and save/restore + * pc and sp. We have to jump to schedinit() because we are going to remap the + * stack. + */ + if (!saved) + save(&balu); + if (setlabel(&p->sched) == 0) + gotolabel(&m->sched); + + /* + * Interrupts are ok now. Note that the process state is still not Running, + * so no rescheduling. + */ spllo(); - p = runproc(); - splhi(); - mapstack(p); - gotolabel(&p->sched); + + /* + * Jumped to by schedinit. Restore the process state. + */ + if (p->fpstate != m->fpstate) + if (p->fpstate == FPinit) { + initfp = 0; + fprestore((FPsave *) &initfp); + m->fpstate = FPinit; + } + else { + fpregrestore(u->fpsave.reg); + fprestore(&u->fpsave); + m->fpstate = FPdirty; + } + if (balu.cr0 != 0xFFFFFFFF) /* balu busy */ + memcpy(BALU, &balu, sizeof balu); + + /* + * Complete restoring the process. + */ + restore(); } void @@ -135,6 +250,10 @@ ready(Proc *p) { int s; + if (p->spin) { + p->state = Running; + return; + } s = splhi(); lock(&runq); p->rnext = 0; @@ -148,42 +267,6 @@ ready(Proc *p) splx(s); } -void -checksched(void) /* just for efficiency; don't sched if no need */ -{ - if(runq.head) - sched(); -} - -/* - * Always called spllo - */ -Proc* -runproc(void) -{ - Proc *p; - -loop: - do; while(runq.head == 0); - splhi(); - lock(&runq); - p = runq.head; - if(p==0 || p->mach){ /* p->mach==0 only when process state is saved */ - unlock(&runq); - spllo(); - goto loop; - } - if(p->rnext == 0) - runq.tail = 0; - runq.head = p->rnext; - if(p->state != Ready) - print("runproc %s %d %s\n", p->text, p->pid, statename[p->state]); - unlock(&runq); - p->state = Scheding; - spllo(); - return p; -} - Proc* newproc(void) { @@ -204,6 +287,7 @@ loop: p->child = 0; p->exiting = 0; p->fpstate = FPinit; + p->kp = 0; memset(p->seg, 0, sizeof p->seg); lock(&pidalloc); p->pid = ++pidalloc.pid; @@ -530,6 +614,12 @@ pexit(char *s, int freemem) lock(&procalloc); /* sched() can't do this */ lock(&c->debug); /* sched() can't do this */ c->state = Moribund; + + /* + * Call the scheduler. This process gets cleaned up in restore() by the next + * process that runs. That means that if there is no other process, we'll + * hang around for a little while. + */ sched(); /* never returns */ } @@ -582,7 +672,8 @@ proctab(int i) } #include -DEBUG() +void +DEBUG(void) { int i; Proc *p; @@ -612,15 +703,16 @@ kproc(char *name, void (*func)(void *), void *arg) * Kernel stack */ p = newproc(); + p->kp = 1; p->upage = newpage(1, 0, USERADDR|(p->pid&0xFFFF)); k = kmap(p->upage); upa = VA(k); up = (User*)upa; - up->p = p; /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy(up, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ @@ -633,17 +725,14 @@ kproc(char *name, void (*func)(void *), void *arg) for(n=0; n<=up->maxfd; n++) up->fd[n] = 0; up->maxfd = 0; + up->p = p; kunmap(k); /* * Sched */ if(setlabel(&p->sched)){ - u->p = p; - p->state = Running; - p->mach = m; - m->proc = p; - spllo(); + restore(); (*func)(arg); pexit(0, 1); } diff --git a/gnot/screen.c b/gnot/screen.c index d45320d454ab97a2e90544bc0e1257ecbf29e2ff..c8397baae7b6f6f44065eede20a1672851ffb935 100644 --- a/gnot/screen.c +++ b/gnot/screen.c @@ -24,6 +24,8 @@ void duartinit(void); int duartacr; int duartimr; +void (*kprofp)(ulong); + GBitmap gscreen = { (ulong*)((4*1024*1024-256*1024)|KZERO), /* BUG */ @@ -287,7 +289,7 @@ duartbreak(int ms) } enum{ - Kptime=200 /* about once per ms */ + Kptime=200 }; void duartstarttimer(void) @@ -349,7 +351,8 @@ duartintr(Ureg *ur) * Is it 0? */ if(cause & IM_CRDY){ -/* kproftimer(ur->pc);/**/ + if(kprofp) + (*kprofp)(ur->pc); c = duart[1].scc_ropbc; duart[0].ctur = (Kptime)>>8; duart[0].ctlr = (Kptime)&255; diff --git a/gnot/sturp.c b/gnot/sturp.c index ea00165ad804554504ed685840e2d370f762ae0d..f2eccd03a43ff7b7ed3a3d845a3da878bc3c3004 100644 --- a/gnot/sturp.c +++ b/gnot/sturp.c @@ -11,7 +11,7 @@ enum { Nmask= 0x7, }; -#define DPRINT if(q->flag&QDEBUG)kprint +#define DPRINT if(q->flag&QDEBUG)print typedef struct Urp Urp; @@ -33,7 +33,7 @@ struct urpstat { } urpstat; struct Urp { - QLock; + Lock; short state; /* flags */ Rendez r; /* process waiting for close */ @@ -140,10 +140,10 @@ urpopen(Queue *q, Stream *s) * find a free urp structure */ for(up = urp; up < &urp[conf.nurp]; up++){ - qlock(up); + lock(up); if(up->state == 0) break; - qunlock(up); + unlock(up); } if(up == &urp[conf.nurp]){ q->ptr = 0; @@ -155,7 +155,7 @@ urpopen(Queue *q, Stream *s) up->rq = q; up->wq = q->other; up->state = OPEN; - qunlock(up); + unlock(up); initinput(up, 0); initoutput(up, 0); @@ -236,7 +236,10 @@ urpclose(Queue *q) while(up->kstarted) sleep(&up->r, isdead, up); + lock(up); up->state = 0; + up->rq = 0; + unlock(up); } /* @@ -990,15 +993,18 @@ urptimer(Alarm *a) { Urp *up; Urp *last; - Queue *q; cancel(a); alarm(500, urptimer, 0); for(up = urp, last = &urp[conf.nurp]; up < last; up++){ if(up->state==0) continue; - if(up->rq && todo(up)) - wakeup(&up->rq->r); + if(up->rq && canlock(up)){ + if(up->rq && NOW>up->timer + && ((up->state&INITING) || up->unechoed!=up->next)) + wakeup(&up->rq->r); + unlock(up); + } } } diff --git a/gnot/sysproc.c b/gnot/sysproc.c index 6c76c2bca961311f8bc90c24fbea7f2eb18428d7..dc46af05b2badb2fc19fc4f87add841391025053 100644 --- a/gnot/sysproc.c +++ b/gnot/sysproc.c @@ -41,6 +41,7 @@ sysfork(ulong *arg) /* * Save time: only copy u-> data and useful stack */ + clearmmucache(); memcpy((void*)upa, u, sizeof(User)); n = USERADDR+BY2PG - (ulong)&lastvar; n = (n+32) & ~(BY2WD-1); /* be safe & word align */ @@ -128,11 +129,8 @@ sysfork(ulong *arg) * Sched */ if(setlabel(&p->sched)){ - u->p = p; - p->state = Running; - p->mach = m; - m->proc = p; - spllo(); + clearmmucache(); + restore(); return 0; } p->pop = u->p; @@ -147,6 +145,7 @@ sysfork(ulong *arg) memcpy(p->text, u->p->text, NAMELEN); ready(p); flushmmu(); + clearmmucache(); return pid; } @@ -361,6 +360,7 @@ sysexec(ulong *arg) unlock(o); flushmmu(); + clearmmucache(); ((Ureg*)UREGADDR)->pc = exec.entry; sp = (ulong*)(USTKTOP - ssize); *--sp = nargs; diff --git a/port/devdk.c b/port/devdk.c index a4398196eaa28ade1093c3f1392e89c5b134b528..a1d628c6f81830bf1cb3298890d062b07a395a2f 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -498,6 +498,14 @@ dkmuxconfig(Dk *dp, Block *bp) dkopen(c, ORDWR); dp->csc = c; + /* + * tell datakit we've rebooted. It should close all channels. + */ + if(dp->restart) { + DPRINT("dkmuxconfig: restart %s\n", dp->name); + dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); + } + /* * start a process to deal with it */ @@ -1315,16 +1323,6 @@ dkcsckproc(void *a) dp = (Dk *)a; - /* - * tell datakit we've rebooted. It should close all channels. - */ - if(dp->restart) { - DPRINT("dkcsckproc: restart %s\n", dp->name); - dkmesg(dp, T_ALIVE, D_RESTART, 0, 0); - } - DPRINT("dkcsckproc: closeall %s\n", dp->name); - dkmesg(dp, T_CHG, D_CLOSEALL, 0, 0); - /* * loop forever listening */ diff --git a/port/devkprof.c b/port/devkprof.c index fe531eae292c5666f1014db79faf53f90d6dd190..76ca8bb1156cf87b79a44da4500a75cbab4f20d6 100644 --- a/port/devkprof.c +++ b/port/devkprof.c @@ -30,9 +30,12 @@ Dirtab kproftab[Nkproftab]={ "kpstop", Kprofstopqid, 0, 0600, }; +void kproftimer(ulong); + void kprofreset(void) { + kprofp = kproftimer; } void @@ -157,7 +160,12 @@ kprofwrite(Chan *c, char *a, long n) void kproftimer(ulong pc) { - extern ulong splpc; + /* + * if the pc is coming out of slplo pr splx, then use + * the pc saved when we went splhi. + */ + if(pc>=(ulong)spllo && pc<=(ulong)spldone) + pc = m->splpc; timerbuf[0]++; if(KTZERO<=pc && pcthdr.type == Tread){ - if(mh->rhdr.count>497 && mh->rhdr.data[497]==011) - print("*497==11 %lux\n", &mh->rhdr.data[497]); + if(mh->thdr.type == Tread) memcpy(mh->thdr.data, mh->rhdr.data, mh->rhdr.count); - } mbfree(mh->mbr); mbfree(mbw); poperror(); diff --git a/port/sturp.c b/port/sturp.c index 806825ae4a491e7dacf47bf1de5da37620153ffd..f2eccd03a43ff7b7ed3a3d845a3da878bc3c3004 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -33,7 +33,7 @@ struct urpstat { } urpstat; struct Urp { - QLock; + Lock; short state; /* flags */ Rendez r; /* process waiting for close */ @@ -140,10 +140,10 @@ urpopen(Queue *q, Stream *s) * find a free urp structure */ for(up = urp; up < &urp[conf.nurp]; up++){ - qlock(up); + lock(up); if(up->state == 0) break; - qunlock(up); + unlock(up); } if(up == &urp[conf.nurp]){ q->ptr = 0; @@ -155,7 +155,7 @@ urpopen(Queue *q, Stream *s) up->rq = q; up->wq = q->other; up->state = OPEN; - qunlock(up); + unlock(up); initinput(up, 0); initoutput(up, 0); @@ -236,7 +236,10 @@ urpclose(Queue *q) while(up->kstarted) sleep(&up->r, isdead, up); + lock(up); up->state = 0; + up->rq = 0; + unlock(up); } /* @@ -465,6 +468,7 @@ urpiput(Queue *q, Block *bp) case ACK+4: case ACK+5: case ACK+6: case ACK+7: case ECHO+0: case ECHO+1: case ECHO+2: case ECHO+3: case ECHO+4: case ECHO+5: case ECHO+6: case ECHO+7: + DPRINT("rACK %ux\n", ctl); rcvack(up, ctl); break; @@ -695,15 +699,18 @@ static void sendctl(Urp *up, int ctl) { Block *bp; + Queue *q; - if(QFULL(up->wq->next)) + q = up->wq; + if(QFULL(q->next)) return; bp = allocb(1); bp->wptr = bp->lim; bp->rptr = bp->lim-1; *bp->rptr = ctl; bp->flags |= S_DELIM; - PUTNEXT(up->wq, bp); + PUTNEXT(q, bp); + DPRINT("sCTL %ulx\n", ctl); } /* @@ -762,9 +769,11 @@ sendblock(Urp *up, int bn) { Block *bp, *m, *nbp; int n; + Queue *q; + q = up->wq; up->timer = NOW + MSrexmit; - if(QFULL(up->wq->next)) + if(QFULL(q->next)) return; /* @@ -781,7 +790,7 @@ sendblock(Urp *up, int bn) nbp->rptr = bp->rptr; nbp->wptr = bp->wptr; nbp->flags |= S_DELIM; - PUTNEXT(up->wq, m); + PUTNEXT(q, m); /* * message 2, the block length and the SEQ @@ -794,7 +803,8 @@ sendblock(Urp *up, int bn) m->rptr[1] = n; m->rptr[2] = n<<8; m->flags |= S_DELIM; - PUTNEXT(up->wq, m); + PUTNEXT(q, m); + DPRINT("sb %d\n", bn); } /* @@ -945,8 +955,8 @@ todo(void *arg) return (up->state&INITING) ? NOW>up->timer /* time to INIT1 */ : ((up->unechoed!=up->next && NOW>up->timer) /* time to ENQ */ - || WINDOW(up)>0 && up->next!=up->nxb - || (!QFULL(up->rq->next) && up->iseq!=(up->lastecho&7))); /* time to ECHO */ + || (WINDOW(up)>0 && (up->next!=up->nxb || up->wq->first)) /* open xmit window */ + || (up->iseq!=(up->lastecho&7) && !QFULL(up->rq->next))); /* time to ECHO */ } static void urpkproc(void *arg) @@ -983,15 +993,18 @@ urptimer(Alarm *a) { Urp *up; Urp *last; - Queue *q; cancel(a); alarm(500, urptimer, 0); for(up = urp, last = &urp[conf.nurp]; up < last; up++){ if(up->state==0) continue; - if(up->rq && todo(up)) - wakeup(&up->rq->r); + if(up->rq && canlock(up)){ + if(up->rq && NOW>up->timer + && ((up->state&INITING) || up->unechoed!=up->next)) + wakeup(&up->rq->r); + unlock(up); + } } } diff --git a/port/sysfile.c b/port/sysfile.c index 25d4d64c4891ebe921e8572d48c4e7540e9dceac..47b648148f97da2254b18c2d6298b5681eac51c1 100644 --- a/port/sysfile.c +++ b/port/sysfile.c @@ -181,7 +181,7 @@ sysread(ulong *arg) long n; c = fdtochan(arg[0], 0); - validaddr(arg[1], arg[2], 0); + validaddr(arg[1], arg[2], 1); qlock(c); if(waserror()){ qunlock(c); diff --git a/power/main.c b/power/main.c index 458e238f7883735914fd14499ca67c5c9e443890..ce17bacbf901e576974297adc1946b8bab1072b9 100644 --- a/power/main.c +++ b/power/main.c @@ -121,7 +121,6 @@ ioboardinit(void) maxlevel = 8; noforce = 0; } - print("IO %d\n", ioid); /* * reset VME bus (MODEREG is on the IO2) @@ -590,7 +589,7 @@ confinit(void) /* * set minimal default values */ - conf.nmach = 1; + conf.nmach = 2; conf.nmod = 2000; conf.nalarm = 10000; conf.norig = 500;