From 2f9960b6a2a96ce115350b9b954cab1915edfd22 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Wed, 22 May 1996 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1996-05-22 --- pc/ether589.c | 6 +--- port/proc.c | 1 + port/taslock.c | 82 ++++++++++++++++++++++++++++++++------------------ 3 files changed, 54 insertions(+), 35 deletions(-) diff --git a/pc/ether589.c b/pc/ether589.c index 8a30d22ff61d72644738b1d5b4d4aeec939e50d7..6e2b7127cd002d7ff7b88a31d8cfa47d70eea57f 100644 --- a/pc/ether589.c +++ b/pc/ether589.c @@ -46,7 +46,6 @@ static int configASIC(Ether *ether, int port, int xcvr) { ushort x; -int r; /* set Window 0 configuration registers */ COMMAND(port, SelectWindow, 0); @@ -54,7 +53,6 @@ int r; /* ROM size & base - must be set before we can access ROM */ /* transceiver type is 2 for 'figure it out' */ x = ins(port + AddressConfig); -print("x = %uX\n", x); outs(port + AddressConfig, (x & 0xf0) | xcvr); /* IRQ must be 3 on 3C589 */ @@ -70,9 +68,7 @@ print("x = %uX\n", x); x = ins(port+EEPROMdata); outs(port + ProductID, x); - r = ether509reset(ether); - outs(port + ResourceConfig, 0x3f00); - return r; + return ether509reset(ether); } static int diff --git a/port/proc.c b/port/proc.c index 5d92c7dc12e7fc654e0cd943b581d65d7e4a9873..c0b1e1a1095987015a700544cf68a8d058ec4ded 100644 --- a/port/proc.c +++ b/port/proc.c @@ -327,6 +327,7 @@ newproc(void) p->wired = 0; p->ureg = 0; p->error[0] = '\0'; + p->lockpri = 0; memset(p->seg, 0, sizeof p->seg); p->pid = incref(&pidalloc); p->noteid = incref(¬eidalloc); diff --git a/port/taslock.c b/port/taslock.c index a8a189af82ba7f52d549e8605b108129c94279cd..789ed0859c3f19860746a8cc5851fa918131dad3 100644 --- a/port/taslock.c +++ b/port/taslock.c @@ -13,41 +13,60 @@ lockloop(Lock *l, ulong pc) dumpaproc(up); } +#define LOCKLOOP 100000000 /* to detect a lock loop */ +#define SPINLOOP 10000000 /* to keep tas's off the bus */ + void lock(Lock *l) { - int pri, i; - ulong pc; + int i, pri, spins; + ulong pc, pid; pc = getcallerpc(l); + if(up){ + pid = up->pid; + pri = up->priority; + } else { + pid = 0; + pri = 0; + } - if(up == 0) { - for(i=0; i<1000000; i++) - if(tas(&l->key) == 0){ - l->pc = pc; - l->pri = 0; - return; - } - lockloop(l, pc); + /* quick try, it might work */ + if(tas(&l->key) == 0){ + l->pc = pc; + l->pid = pid; + l->pri = pri; return; } - /* priority interacts with code in ready() in proc.c */ - pri = up->priority; + spins = 0; + for(;;){ + i = 0; + while(l->key) + if(i++ > SPINLOOP){ + /* look for lock loops */ + if(spins++ > LOCKLOOP/SPINLOOP){ + spins = 0; + lockloop(l, pc); + } + + /* possible priority inversion, try switching priority */ + if(up && up->state == Running) + if(getstatus()&IE) { +print("priority inversion\n"); + up->lockpri = l->pri; + sched(); + } + } - for(i=0; i<1000000; i++){ - up->lockpri = l->pri; /* assume priority of process holding lock */ if(tas(&l->key) == 0){ - l->pri = pri; - up->lockpri = 0; /* back to normal priority */ l->pc = pc; + l->pid = pid; + l->pri = pri; + up->lockpri = 0; return; } - if(conf.nmach == 1 && up->state == Running && (getstatus()&IE)) - sched(); } - lockloop(l, pc); - up->lockpri = 0; /* back to normal priority */ } void @@ -64,6 +83,7 @@ ilock(Lock *l) l->sr = x; l->pc = pc; l->pid = pid; + l->pri = 0; return; } @@ -74,6 +94,7 @@ ilock(Lock *l) l->sr = x; l->pc = pc; l->pid = pid; + l->pri = 0; return; } } @@ -82,25 +103,25 @@ ilock(Lock *l) int canlock(Lock *l) { - int pri; - - if(up) - pri = up->priority; - else - pri = 0; - if(tas(&l->key)) { - l->pc = getcallerpc(l); + if(tas(&l->key)) return 0; + + l->pc = getcallerpc(l); + if(up){ + l->pid = up->pid; + l->pri = up->priority; + } else { + l->pid = 0; + l->pri = 0; } - l->pri = pri; return 1; } void unlock(Lock *l) { - l->pc = 0; l->key = 0; + l->pc = 0; l->pri = 0; } @@ -112,5 +133,6 @@ iunlock(Lock *l) sr = l->sr; l->key = 0; l->pc = 0; + l->pri = 0; splx(sr); }