M gnot/main.c => gnot/main.c +1 -0
@@ 320,6 320,7 @@ confinit(void)
conf.copymode = 0; /* copy on write */
conf.portispaged = 0;
conf.cntrlp = 0;
+ conf.nconc = 2;
confinit1(mul);
}
M port/devbit.c => port/devbit.c +7 -5
@@ 839,11 839,13 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
error(Ebadblt);
q0 = GLONG(p+1);
q1 = GLONG(p+5);
- for(i=0; i<bit.nsubfont; i++){
- f = bit.subfont[i];
- if(f && f->qid[0]==q0 && f->qid[1]==q1)
- goto sfcachefound;
- }
+ i = 0;
+ if(q0 != ~0)
+ for(; i<bit.nsubfont; i++){
+ f = bit.subfont[i];
+ if(f && f->qid[0]==q0 && f->qid[1]==q1)
+ goto sfcachefound;
+ }
error(Esfnotcached);
sfcachefound:
M port/fault.c => port/fault.c +2 -4
@@ 5,8 5,6 @@
#include "fns.h"
#include "../port/error.h"
-#define DPRINT
-
void faulterror(char*);
int
@@ 104,8 102,7 @@ fixfault(Segment *s, ulong addr, int read, int doputmmu)
if(type == SG_SHARED)
goto done;
- if(read)
- if(conf.copymode == 0) {
+ if(read && conf.copymode == 0) {
mmuphys = PPN((*pg)->pa) | PTERONLY|PTEVALID;
(*pg)->modref |= PG_REF;
break;
@@ 258,6 255,7 @@ pio(Segment *s, ulong addr, ulong soff, Page **p)
cachepage(new, &swapimage);
putswap(*p);
*p = new;
+/* print("l %lux %d\n", addr, daddr);*/
}
else
putpage(new);
M port/page.c => port/page.c +22 -3
@@ 193,12 193,14 @@ duppage(Page *p) /* Always call with p locked */
{
Page *np;
- if(p->image == &swapimage)
+ /* No dup for swap pages */
+ if(p->image == &swapimage) {
+ uncachepage(p);
return;
+ }
lock(&palloc);
-
- /* No freelist cache when memory is very low, No dup for swap pages */
+ /* No freelist cache when memory is very low */
if(palloc.freecount < swapalloc.highwater) {
unlock(&palloc);
uncachepage(p);
@@ 288,6 290,23 @@ cachepage(Page *p, Image *i)
unlock(&palloc.hashlock);
}
+void
+cachedel(Image *i, ulong daddr)
+{
+ Page *f, **l;
+
+ lock(&palloc.hashlock);
+ l = &palloc.hash[PGHFUN(i, daddr)];
+ for(f = *l; f; f = f->hash) {
+ if(f->image == i && f->daddr == daddr) {
+ *l = f->hash;
+ break;
+ }
+ l = &f->hash;
+ }
+ unlock(&palloc.hashlock);
+}
+
Page *
lookpage(Image *i, ulong daddr)
{
M port/portfns.h => port/portfns.h +1 -0
@@ 5,6 5,7 @@ Image* attachimage(int, Chan*, ulong, ulong);
int blen(Block *);
int bround(Block *, int);
void buzz(int, int);
+void cachedel(Image*, ulong);
void cachepage(Page*, Image*);
int cangetc(void*);
int canlock(Lock*);
M port/swap.c => port/swap.c +1 -1
@@ 253,7 253,7 @@ pagepte(int type, Segment *s, Page **pg)
case SG_SHARED:
case SG_SHDATA:
daddr = newswap();
-
+ cachedel(&swapimage, daddr);
lock(outp);
outp->ref++;
uncachepage(outp);
M power/dat.h => power/dat.h +2 -2
@@ 178,14 178,14 @@ struct User
{
Proc *p;
FPsave fpsave; /* address of this is known by db */
+ int scallnr; /* sys call number - known by db */
+ Sargs s; /* address of this is known by db */
int nerrlab;
Label errlab[NERR];
char error[ERRLEN];
char elem[NAMELEN]; /* last name element from namec */
Chan *slash;
Chan *dot;
- int scallnr; /* sys call number */
- Sargs s;
/*
* Rest of structure controlled by devproc.c and friends.
* qlock(&p->debug) to modify.
M power/fns.h => power/fns.h +1 -0
@@ 37,6 37,7 @@ void lanceparity(void);
void lancesetup(Lance*);
void launchinit(void);
void launch(int);
+int muxlock(int*, int*);
void newstart(void);
int newtlbpid(Proc*);
void novme(int);
M power/l.s => power/l.s +26 -0
@@ 125,6 125,32 @@ TEXT spllo(SB), $0
NOOP
RET
+TEXT muxlock(SB),$0
+
+ MOVW R1, R2 /* sbsem */
+ MOVW 4(FP), R3 /* lk->val */
+
+ MOVW M(STATUS), R5 /* splhi */
+ AND $~IEC, R5, R4
+ MOVW R4, M(STATUS)
+
+ MOVW 0(R2),R4 /* grab sbsem */
+ AND $1, R4
+ BNE R4, f1
+ MOVW 0(R3),R4
+ BNE R4, f0
+
+ MOVW $1, R1
+ MOVW R1, 0(R3) /* lk->val = 1 */
+ MOVW R0, 0(R2) /* *sbsem = 0 */
+ MOVW R5, M(STATUS) /* splx */
+ RET
+
+f0: MOVW R0, 0(R2) /* *sbsem = 0 */
+f1: MOVW R5, M(STATUS) /* splx */
+ MOVW R0, R1 /* return 0 */
+ RET
+
TEXT spldone(SB), $0
RET
M power/lock.c => power/lock.c +20 -43
@@ 7,8 7,8 @@
#include "../port/error.h"
/*
- * The hardware semaphores are strange. 64 per page, replicated 16 times
- * per page, 1024 pages of them. Only the low bit is meaningful.
+ * The hardware semaphores are strange. Only 64 per page can be used,
+ * 1024 pages of them. Only the low bit is meaningful.
* Reading an unset semaphore sets the semaphore and returns the old value.
* Writing a semaphore sets the value, so writing 0 resets (clears) the semaphore.
*/
@@ 28,20 28,25 @@ struct
}semalloc;
Page lkpgheader[NSEMPG];
-#define lhash(laddr) ((int)laddr>>2)&(((NSEMPG-ULOCKPG)*(BY2PG>>2))-1)
+#define lhash(laddr) ((int)laddr>>2)&(((NSEMPG-ULOCKPG)*(BY2PG>>2))-1)&~0x3c0
void
lockinit(void)
{
- memset(semalloc.bmap, 0, sizeof(semalloc.bmap));
+ int *sbsem, h, i;
+
/*
* Initialise the system semaphore hardware
*/
- memset(SBSEM, 0, (NSEMPG-ULOCKPG)*BY2PG);
+ for(i = 0; i < (NSEMPG-ULOCKPG)*BY2PG; i += 4) {
+ h = lhash(i);
+ sbsem = (int*)SBSEM+h;
+ *sbsem = 0;
+ }
semalloc.ulockpg = ULOCKPG;
}
-/* Moral equivalent of newpage for pages of hardware locks */
+/* equivalent of newpage for pages of hardware locks */
Page*
lkpage(ulong va)
{
@@ 56,9 61,9 @@ lkpage(ulong va)
return 0;
}
top = &semalloc.bmap[NSEMPG];
- for(p = semalloc.bmap; *p && p < top; p++)
+ for(p = semalloc.bmap; p < top && *p; p++)
;
- if(p == top)
+ if(p >= top)
panic("lkpage");
*p = 1;
@@ 90,28 95,16 @@ lkpgfree(Page *pg)
void
lock(Lock *lk)
{
- int *hwsem;
- int i, hash;
+ int *hwsem, hash;
hash = lhash(lk);
hwsem = (int*)SBSEM+hash;
- i = 1000000;
for(;;) {
- if((*hwsem & 1) == 0) {
- if(lk->val)
- *hwsem = 0;
- else {
- lk->val = 1;
- *hwsem = 0;
- lk->pc = getcallerpc(lk);
- return;
- }
- }
- while(lk->val && i)
- i--;
- if(i <= 0)
- break;
+ if(muxlock(hwsem, &lk->val))
+ return;
+ while(lk->val)
+ ;
}
print("lock loop %lux pc %lux held by pc %lux\n", lk, getcallerpc(lk), lk->pc);
dumpstack();
@@ 120,26 113,10 @@ lock(Lock *lk)
int
canlock(Lock *lk)
{
- int *hwsem;
- int i, hash;
+ int hash;
hash = lhash(lk);
- hwsem = (int*)SBSEM+hash;
-
- for(;;) {
- if((*hwsem & 1) == 0) {
- if(lk->val)
- *hwsem = 0;
- else {
- lk->val = 1;
- *hwsem = 0;
- lk->pc = getcallerpc(lk);
- return 1;
- }
- }
- if(lk->val)
- return 0;
- }
+ return muxlock((int*)SBSEM+hash, &lk->val);
}
void