M pc/ether589.c => pc/ether589.c +1 -5
@@ 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
M port/proc.c => port/proc.c +1 -0
@@ 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);
M port/taslock.c => port/taslock.c +52 -30
@@ 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);
}