M carrera/dat.h => carrera/dat.h +1 -1
@@ 28,7 28,6 @@ struct Lock
ulong sr;
ulong pc;
Proc *p;
- ushort pri;
ushort isilock;
};
@@ 114,6 113,7 @@ struct Mach
int speed; /* cpu speed */
ulong delayloop; /* for the delay() routine */
int nrdy;
+ ulong fairness; /* for runproc */
int pfault;
int cs;
M carrera/l.s => carrera/l.s +2 -0
@@ 103,6 103,8 @@ TEXT splhi(SB), $0
TEXT splx(SB), $0
MOVW R31, 12(R(MACH)) /* save PC in m->splpc */
+
+TEXT splxpc(SB), $0 /* for iunlock */
MOVW M(STATUS), R2
WAIT
AND $IE, R1
M pc/dat.h => pc/dat.h +2 -1
@@ 28,7 28,6 @@ struct Lock
ulong sr;
ulong pc;
Proc *p;
- ushort pri;
ushort isilock;
};
@@ 162,6 161,8 @@ struct Mach
Lock alarmlock; /* access to alarm list */
void* alarm; /* alarms bound to this clock */
+ ulong fairness; /* for runproc */
+
int tlbfault;
int tlbpurge;
int pfault;
M pc/etherelnk3.c => pc/etherelnk3.c +2 -0
@@ 1763,6 1763,8 @@ else
for(i = 0; i < ether->nopt; i++){
if(cistrcmp(ether->opt[i], "fullduplex") == 0)
an |= 0x0100;
+ else if(cistrcmp(ether->opt[i], "100BASE-TXFD") == 0)
+ an |= 0x0100;
else if(cistrcmp(ether->opt[i], "force100") == 0)
an |= 0x0080;
}
M pc/l.s => pc/l.s +1 -1
@@ 441,7 441,7 @@ TEXT splx(SB), $0
MOVL (SP), BX
MOVL BX, (AX)
-TEXT _splx(SB), $0 /* for iunlock */
+TEXT splxpc(SB), $0 /* for iunlock */
MOVL s+0(FP), AX
PUSHL AX
POPFL
M pc/trap.c => pc/trap.c +0 -4
@@ 419,10 419,6 @@ syscall(Ureg* ureg)
splhi();
notify(ureg);
}
- if (up->nlocks != 0) {
- print("nlock = %d\n", up->nlocks);
- up->nlocks = 0;
- }
}
/*
M port/portdat.h => port/portdat.h +2 -2
@@ 518,7 518,7 @@ enum
NNOTE = 5,
Nrq = 20, /* number of scheduler priority levels */
- PriLock = 19, /* priority for processes holding locks */
+ PriLock = 0, /* priority for processes waiting on a lock */
PriNormal = 10, /* base priority for normal processes */
PriKproc = 13, /* base priority for kernel processes */
PriRoot = 13, /* base priority for root processes */
@@ 601,7 601,7 @@ struct Proc
Note lastnote;
int (*notify)(void*, char*);
- int nlocks; /* Number of locks held */
+ int lockwait; /* waiting for lock to be released */
Mach *wired;
Mach *mp; /* machine this process last ran on */
M port/portfns.h => port/portfns.h +1 -0
@@ 284,6 284,7 @@ void* smalloc(ulong);
int splhi(void);
int spllo(void);
void splx(int);
+void splxpc(int);
void srvrecover(Chan*, Chan*);
void swapinit(void);
Block* trimblock(Block*, int, int);
M port/proc.c => port/proc.c +6 -3
@@ 158,6 158,10 @@ ready(Proc *p)
if(pri < PriNormal && p->basepri > PriNormal)
pri = PriNormal;
+ /* stick at low priority any process waiting for a lock */
+ if(p->lockwait)
+ pri = PriLock;
+
p->priority = pri;
rq = &runq[p->priority];
@@ 198,7 202,7 @@ loop:
* processor can run given affinity constraints
* and that hasn't run in a while
*/
- if((m->ticks & 3) == 0){
+ if((m->fairness++ & 3) == 0){
for(rq = runq; rq < &runq[Nrq]; rq++){
p = rq->head;
if(p == 0)
@@ 331,7 335,6 @@ newproc(void)
panic("pidalloc");
if(p->kstack == 0)
p->kstack = smalloc(KSTACK);
- p->nlocks = 0;
return p;
}
@@ 893,7 896,7 @@ dumpaproc(Proc *p)
s = p->psstate;
if(s == 0)
s = "kproc";
- print("%3d:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux\n",
+ print("%3d:%10s pc %8lux dbgpc %8lux %8s (%s) ut %ld st %ld bss %lux pri %d\n",
p->pid, p->text, p->pc, dbgpc(p), s, statename[p->state],
p->time[0], p->time[1], bss, p->priority);
}
M port/taslock.c => port/taslock.c +48 -46
@@ 5,12 5,23 @@
#include "fns.h"
#include "../port/error.h"
+struct {
+ ulong locks;
+ ulong glare;
+ ulong inglare;
+} lockstats;
+
void
lockloop(Lock *l, ulong pc)
{
+ Proc *p;
+
+ p = l->p;
print("lock loop key 0x%lux pc 0x%lux held by pc 0x%lux proc %d\n",
- l->key, pc, l->pc, l->p ? l->p->pid : 0);
+ l->key, pc, l->pc, p ? p->pid : 0);
dumpaproc(up);
+ if(p != nil)
+ dumpaproc(p);
if(up && up->state == Running && islo())
sched();
@@ 19,27 30,33 @@ lockloop(Lock *l, ulong pc)
void
lock(Lock *l)
{
- int i;
- ulong pc;
+ int i, cansched;
+ ulong pc, oldpri;
pc = getcallerpc(l);
+lockstats.locks++;
if(tas(&l->key) == 0){
l->pc = pc;
l->p = up;
l->isilock = 0;
- if(up){
- up->nlocks++;
- l->pri = up->priority;
- up->priority = PriLock;
- }
return;
}
+lockstats.glare++;
+ cansched = up != nil && up->state == Running;
+ if(cansched){
+ oldpri = up->priority;
+ up->lockwait = 1;
+ up->priority = PriLock;
+ } else
+ oldpri = 0;
+
for(;;){
+lockstats.inglare++;
i = 0;
while(l->key){
- if(conf.nmach < 2){
+ if(conf.nmach < 2 && cansched){
if(i++ > 1000){
i = 0;
lockloop(l, pc);
@@ 56,10 73,9 @@ lock(Lock *l)
l->pc = pc;
l->p = up;
l->isilock = 0;
- if(up){
- up->nlocks++;
- l->pri = up->priority;
- up->priority = PriLock;
+ if(cansched){
+ up->lockwait = 0;
+ up->priority = oldpri;
}
return;
}
@@ 70,14 86,14 @@ void
ilock(Lock *l)
{
ulong x;
- ulong pc;
+ ulong pc, oldpri;
+ int cansched;
pc = getcallerpc(l);
+lockstats.locks++;
x = splhi();
if(tas(&l->key) == 0){
- if (up)
- up->nlocks++;
l->sr = x;
l->pc = pc;
l->p = up;
@@ 85,21 101,32 @@ ilock(Lock *l)
return;
}
+lockstats.glare++;
+ cansched = up != nil && up->state == Running;
+ if(cansched){
+ oldpri = up->priority;
+ up->lockwait = 1;
+ up->priority = PriLock;
+ } else
+ oldpri = 0;
if(conf.nmach < 2)
panic("ilock: no way out: pc %uX\n", pc);
for(;;){
+lockstats.inglare++;
splx(x);
while(l->key)
;
x = splhi();
if(tas(&l->key) == 0){
- if (up)
- up->nlocks++;
l->sr = x;
l->pc = pc;
l->p = up;
l->isilock = 1;
+ if(cansched){
+ up->lockwait = 0;
+ up->priority = oldpri;
+ }
return;
}
}
@@ 114,41 141,19 @@ canlock(Lock *l)
l->pc = getcallerpc(l);
l->p = up;
l->isilock = 0;
- if(up){
- up->nlocks++;
- l->pri = up->priority;
- up->priority = PriLock;
- }
return 1;
}
void
unlock(Lock *l)
{
- int p;
- ulong pc;
-
- pc = getcallerpc(l);
- p = l->pri;
if(l->key == 0)
print("unlock: not locked: pc %uX\n", getcallerpc(l));
if(l->isilock)
print("iunlock of lock: pc %lux, held by %lux\n", getcallerpc(l), l->pc);
l->pc = 0;
l->key = 0;
- if(up) {
- if (up != l->p) {
- print("different unlocker 0x%lux pc 0x%lux held by pc 0x%lux proc %d\n",
- l->key, pc, l->pc, l->p ? l->p->pid : 0);
- dumpaproc(up);
- }
- if (--up->nlocks < 0)
- print("number of locks < 0: pc %lux, held by %lux\n",
- getcallerpc(l), l->pc);
- if (p < up->priority)
- up->priority = p;
- }
coherence();
}
@@ 165,11 170,8 @@ iunlock(Lock *l)
sr = l->sr;
l->pc = 0;
l->key = 0;
- if(up) {
- if (--up->nlocks < 0)
- print("number of locks < 0: pc %lux, held by %lux\n",
- getcallerpc(l), l->pc);
- }
- splx(sr);
coherence();
+
+ m->splpc = getcallerpc(l);
+ splxpc(sr);
}