From 72933d02d507866070b033630dea877c2513c887 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 2 Apr 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-04-02 --- pc/trap.c | 22 +++++++++++++-- port/devcons.c | 6 ++-- port/devsd.c | 4 +-- port/portclock.c | 7 ----- port/proc.c | 22 +-------------- port/qlock.c | 7 ----- port/sd.h | 2 +- port/sysproc.c | 3 -- port/taslock.c | 73 +++++++++++++++++++++++++++++++++++++++++++----- 9 files changed, 93 insertions(+), 53 deletions(-) diff --git a/pc/trap.c b/pc/trap.c index 3a8946bd9869413a54336db7e80b18f2d7968238..f512d6a3be18d61f8293d0c00c8d3d3053c9e11e 100644 --- a/pc/trap.c +++ b/pc/trap.c @@ -303,8 +303,6 @@ trap(Ureg* ureg) postnote(up, 1, buf, NDebug); } else if(vno >= VectorPIC && vno != VectorSYSCALL){ - i8259isr(vno); - /* * An unknown interrupt. * Check for a default IRQ7. This can happen when @@ -313,6 +311,26 @@ trap(Ureg* ureg) * the corresponding bit in the ISR isn't set. * In fact, just ignore all such interrupts. */ + + /* call all interrupt routines, just in case */ + for(i = VectorPIC; i <= MaxIrqLAPIC; i++){ + ctl = vctl[i]; + if(ctl == nil) + continue; + if(!ctl->isintr) + continue; + for(v = ctl; v != nil; v = v->next){ + if(v->f) + v->f(ureg, v->a); + } + /* should we do this? */ + if(ctl->eoi) + ctl->eoi(i); + } + + /* clear the interrupt */ + i8259isr(vno); + print("cpu%d: spurious interrupt %d, last %d", m->machno, vno, m->lastintr); for(i = 0; i < 32; i++){ diff --git a/port/devcons.c b/port/devcons.c index 2f6d29ccd08f797474feea787099d57a1f8d0f7f..700ad119a1d5b6da309ee9e6633dbb3258263a65 100644 --- a/port/devcons.c +++ b/port/devcons.c @@ -15,7 +15,7 @@ Queue* kbdq; /* unprocessed console input */ Queue* lineq; /* processed console input */ Queue* serialoq; /* serial console output */ Queue* kprintoq; /* console output, for /dev/kprint */ -Lock kprintinuse; /* test and set whether /dev/kprint is open */ +ulong kprintinuse; /* test and set whether /dev/kprint is open */ static struct { @@ -595,7 +595,7 @@ consopen(Chan *c, int omode) break; case Qkprint: - if(!canlock(&kprintinuse)){ + if(tas(&kprintinuse) != 0){ c->flag &= ~COPEN; error(Einuse); } @@ -631,7 +631,7 @@ consclose(Chan *c) /* close of kprint allows other opens */ case Qkprint: if(c->flag & COPEN){ - unlock(&kprintinuse); + kprintinuse = 0; qhangup(kprintoq, nil); } break; diff --git a/port/devsd.c b/port/devsd.c index f6ead6ab614775976f0ad63ea377782220c9ddd3..31bf5253a03a675b5d8c30b68640fc02ef43a845 100644 --- a/port/devsd.c +++ b/port/devsd.c @@ -656,7 +656,7 @@ sdopen(Chan* c, int omode) break; case Qraw: c->qid.vers = unit->vers; - if(!canlock(&unit->rawinuse)){ + if(tas(&unit->rawinuse) != 0){ c->flag &= ~COPEN; error(Einuse); } @@ -697,7 +697,7 @@ sdclose(Chan* c) sdev = sdgetdev(DEV(c->qid)); if (sdev) { unit = sdev->unit[UNIT(c->qid)]; - unlock(&unit->rawinuse); + unit->rawinuse = 0; decref(&sdev->r); } break; diff --git a/port/portclock.c b/port/portclock.c index 7a8fe5ef20e17e6e58c3b6796512f8548b25d6f1..1692beb54c460eb1bb4246256dd3c9cb74e2a7cf 100644 --- a/port/portclock.c +++ b/port/portclock.c @@ -5,7 +5,6 @@ #include "fns.h" #include "io.h" #include "ureg.h" -#include "../port/edf.h" void (*kproftimer)(ulong); @@ -76,12 +75,6 @@ portclock(Ureg *ur) if(up == 0 || up->state != Running) return; - // i.e. don't schedule an EDF process here! - if(!isedf(up) && anyready()){ - sched(); - splhi(); - } - /* user profiling clock */ if(userureg(ur)) { (*(ulong*)(USTKTOP-BY2WD)) += TK2MS(1); diff --git a/port/proc.c b/port/proc.c index 74262ef69ff86f583d4aa25a9090900c70e93161..756a2df76ed06a69f88aafb77c369a87fd8f2e75 100644 --- a/port/proc.c +++ b/port/proc.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include "../port/edf.h" int nrdy; Ref noteidalloc; @@ -57,9 +56,6 @@ schedinit(void) /* never returns */ case Moribund: up->state = Dead; - if (isedf(up)) - edf_bury(up); - /* * Holding locks from pexit: * procalloc @@ -112,7 +108,7 @@ sched(void) int anyready(void) { - return nrdy || edf_anyready(); + return nrdy; } int @@ -143,11 +139,6 @@ ready(Proc *p) s = splhi(); - if(isedf(p)){ - edf_ready(p); - splx(s); - return; - } if(p->fixedpri){ pri = p->basepri; } else { @@ -198,9 +189,6 @@ runproc(void) Proc *p, *l; ulong rt; - if ((p = edf_runproc()) != nil) - return p; - loop: /* @@ -486,8 +474,6 @@ sleep(Rendez *r, int (*f)(void*), void *arg) unlock(r); // Behind unlock, we may call wakeup on ourselves. - if (isedf(up)) - edf_block(up); gotolabel(&m->sched); } @@ -696,8 +682,6 @@ addbroken(Proc *p) broken.p[broken.n++] = p; qunlock(&broken); - if (isedf(up)) - edf_bury(up); p->state = Broken; p->psstate = 0; sched(); @@ -865,8 +849,6 @@ pexit(char *exitstr, int freemem) lock(&procalloc); lock(&palloc); - if (isedf(up)) - edf_bury(up); up->state = Moribund; sched(); panic("pexit"); @@ -1119,8 +1101,6 @@ procctl(Proc *p) qunlock(&p->debug); splhi(); p->state = Stopped; - if (isedf(up)) - edf_block(up); sched(); p->psstate = state; splx(s); diff --git a/port/qlock.c b/port/qlock.c index a96f85c4bc6bd28f16e84f4c91dca57d37a883ca..71418ed1144510304600d72fa2968f7771ff29b2 100644 --- a/port/qlock.c +++ b/port/qlock.c @@ -3,7 +3,6 @@ #include "mem.h" #include "dat.h" #include "fns.h" -#include "../port/edf.h" struct { ulong rlock; @@ -40,8 +39,6 @@ rwstats.qlockq++; mp->state = Queueing; up->qpc = getcallerpc(&q); unlock(&q->use); - if (isedf(mp)) - edf_block(mp); sched(); } @@ -105,8 +102,6 @@ rwstats.rlockq++; mp->qnext = 0; mp->state = QueueingR; unlock(&q->use); - if (isedf(mp)) - edf_block(mp); sched(); } @@ -163,8 +158,6 @@ rwstats.wlockq++; mp->qnext = 0; mp->state = QueueingW; unlock(&q->use); - if (isedf(mp)) - edf_block(mp); sched(); } diff --git a/port/sd.h b/port/sd.h index 696b9f2810e92bfddb88efde38ced991102dd067..7a50c35e68bc15997dcbe8a684de386cd0efb72e 100644 --- a/port/sd.h +++ b/port/sd.h @@ -38,7 +38,7 @@ typedef struct SDunit { SDperm ctlperm; QLock raw; /* raw read or write in progress */ - Lock rawinuse; /* really just a test-and-set */ + ulong rawinuse; /* really just a test-and-set */ int state; SDreq* req; SDperm rawperm; diff --git a/port/sysproc.c b/port/sysproc.c index 4acaacb1ae733b257527768c43ce605ae65b6fc3..e41c93bfc466d15d2f4c813ccc5b5f40c91edeb4 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include "../port/edf.h" #include @@ -826,8 +825,6 @@ sysrendezvous(ulong *arg) *l = up; up->state = Rendezvous; unlock(up->rgrp); - if (isedf(up)) - edf_block(up); sched(); diff --git a/port/taslock.c b/port/taslock.c index b289750fe4059a205f9b02bbe57f790092960237..4460d8f81a1d08b67fe4e3d3ce0be8355bf2f75c 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -4,7 +4,6 @@ #include "dat.h" #include "fns.h" #include "../port/error.h" -#include "../port/edf.h" struct { ulong locks; @@ -12,6 +11,45 @@ struct { ulong inglare; } lockstats; +typedef struct PC { + ulong pc; + int count; +} PC; + +PC lpcs[1024]; + +void +incpcref(Lock *l) +{ + int i; + + for(i = 0; i < nelem(lpcs)-1; i++){ + if(lpcs[i].pc == l->pc) + break; + if(lpcs[i].pc == 0){ + lpcs[i].pc = l->pc; + break; + } + } + lpcs[i].count++; +} + +void +decpcref(Lock *l) +{ + int i; + + for(i = 0; i < nelem(lpcs)-1; i++){ + if(lpcs[i].pc == l->pc) + break; + if(lpcs[i].pc == 0){ + lpcs[i].pc = l->pc; + break; + } + } + lpcs[i].count--; +} + static void dumplockmem(char *tag, Lock *l) { @@ -51,13 +89,17 @@ lock(Lock *l) pc = getcallerpc(&l); - lockstats.locks++; + lockstats.locks++; /* prevent being scheded */ + if (up) up->nlocks++; if(tas(&l->key) == 0){ + if (up) up->lastlock = l; l->pc = pc; +// incpcref(l); l->p = up; l->isilock = 0; return; } + if (up) up->nlocks--; /* didn't get the lock, allow scheding */ lockstats.glare++; cansched = up != nil && up->state == Running; @@ -85,8 +127,11 @@ lock(Lock *l) } } } + if (up) up->nlocks++; if(tas(&l->key) == 0){ + if (up) up->lastlock = l; l->pc = pc; +// incpcref(l); l->p = up; l->isilock = 0; if(cansched){ @@ -95,6 +140,7 @@ lock(Lock *l) } return; } + if (up) up->nlocks--; } } @@ -110,6 +156,7 @@ ilock(Lock *l) x = splhi(); if(tas(&l->key) == 0){ + if (up) up->lastlock = l; l->sr = x; l->pc = pc; l->p = up; @@ -125,11 +172,10 @@ ilock(Lock *l) up->priority = PriLock; } else oldpri = 0; - if(conf.nmach < 2) -{ -dumplockmem("ilock:", l); + if(conf.nmach < 2){ + dumplockmem("ilock:", l); panic("ilock: no way out: pc %luX\n", pc); -} + } for(;;){ lockstats.inglare++; @@ -138,6 +184,7 @@ dumplockmem("ilock:", l); ; x = splhi(); if(tas(&l->key) == 0){ + if (up) up->lastlock = l; l->sr = x; l->pc = pc; l->p = up; @@ -154,10 +201,15 @@ dumplockmem("ilock:", l); int canlock(Lock *l) { - if(tas(&l->key)) + if (up) up->nlocks++; + if(tas(&l->key)){ + if (up) up->nlocks--; return 0; + } + if (up) up->lastlock = l; l->pc = getcallerpc(&l); +// incpcref(l); l->p = up; l->isilock = 0; return 1; @@ -170,8 +222,15 @@ unlock(Lock *l) print("unlock: not locked: pc %luX\n", getcallerpc(&l)); if(l->isilock) print("unlock of ilock: pc %lux, held by %lux\n", getcallerpc(&l), l->pc); + if(l->p != up) + print("unlock: up changed: pc %lux, acquired at pc %lux, lock p 0x%p, unlock up 0x%p\n", getcallerpc(&l), l->pc, l->p, up); +// decpcref(l); l->pc = 0; l->key = 0; + if (up && --up->nlocks == 0 && up->delaysched){ + up->delaysched = 0; + sched(); + } coherence(); }