From 08147bb60bc03d26c45c129e039fc62e9e1fefe3 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 29 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-29 --- gnot/main.c | 1 + port/devbit.c | 12 ++++++---- port/fault.c | 6 ++--- port/page.c | 25 +++++++++++++++++--- port/portfns.h | 1 + port/swap.c | 2 +- power/dat.h | 4 ++-- power/fns.h | 1 + power/l.s | 26 +++++++++++++++++++++ power/lock.c | 63 ++++++++++++++++---------------------------------- 10 files changed, 83 insertions(+), 58 deletions(-) diff --git a/gnot/main.c b/gnot/main.c index f851ee2fd89c3a77cadcab8e559c828aaf2a1d23..9ce11acd737bc89268d2202586e0ac1a46584ea7 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -320,6 +320,7 @@ confinit(void) conf.copymode = 0; /* copy on write */ conf.portispaged = 0; conf.cntrlp = 0; + conf.nconc = 2; confinit1(mul); } diff --git a/port/devbit.c b/port/devbit.c index 4746678fefe2f0efbf977f50090f042a8905a5d3..8b2b4969266e11f5ecdbf0220338d90bff23c063 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -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; iqid[0]==q0 && f->qid[1]==q1) - goto sfcachefound; - } + i = 0; + if(q0 != ~0) + for(; iqid[0]==q0 && f->qid[1]==q1) + goto sfcachefound; + } error(Esfnotcached); sfcachefound: diff --git a/port/fault.c b/port/fault.c index 5f80f1e38b540817a9479baf942c493430a3dc01..403bf0d43627db4557e0bf70fe53c46d4632fad0 100644 --- a/port/fault.c +++ b/port/fault.c @@ -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); diff --git a/port/page.c b/port/page.c index 90cb28f9906b2bd132b92e09ee2b9616c2484c77..fa290b5f1518e77dd7424a0171a4a39055c97ee2 100644 --- a/port/page.c +++ b/port/page.c @@ -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) { diff --git a/port/portfns.h b/port/portfns.h index 633867afa51f48b2a66b058bbdf37313b8ce3537..f6910f293d445cc52c6e7f52b07b028a660bf1c2 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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*); diff --git a/port/swap.c b/port/swap.c index e9f553456a0dc706076c3d787b14d0e4b9bae0ee..b2cafe2bbfc518b8c7596da521fa8613da2b0fd3 100644 --- a/port/swap.c +++ b/port/swap.c @@ -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); diff --git a/power/dat.h b/power/dat.h index 8b825213f26d3600dd5368916365b0f8229e1384..f25a668a5cf2ce7a63b1c1cc0f48ed5b6f46c41d 100644 --- a/power/dat.h +++ b/power/dat.h @@ -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. diff --git a/power/fns.h b/power/fns.h index 09b34c53dea1e5812670e5a964a2ce750ab8369f..ff0f6a4b256b0fc1fb8b2fcd4df6c8b795f7679d 100644 --- a/power/fns.h +++ b/power/fns.h @@ -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); diff --git a/power/l.s b/power/l.s index bb7ad8ac12bede3512a3bbe4f3a8552ef0392ef4..d4a74107f7c3b96129bdfef7dca9a3555277fac7 100644 --- a/power/l.s +++ b/power/l.s @@ -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 diff --git a/power/lock.c b/power/lock.c index 4f145ab9b49cd7a55a4ae6b027ac01651eddf7b4..1d59d69ba24e2452d868206a9e8cedb5cd38024a 100644 --- a/power/lock.c +++ b/power/lock.c @@ -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