From b7d0c039e165b04d88ecae5736630b9043a8d3be Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Fri, 15 Oct 1993 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1993-10-15 --- carrera/main.c | 6 ++- carrera/trap.c | 1 + port/cache.c | 121 +++++++++++++++++++++++++++++++++++++++++-------- port/chan.c | 7 --- port/devmnt.c | 47 +++++++++++++------ port/page.c | 28 ++++++++++++ port/portfns.h | 3 ++ power/dat.h | 10 ++++ 8 files changed, 181 insertions(+), 42 deletions(-) diff --git a/carrera/main.c b/carrera/main.c index 3b6eea4603bd0104e6874b7fbce99e585ebb34ba..17b86fd8e0928f7e6cafd5c47da67c8cadd27cd4 100644 --- a/carrera/main.c +++ b/carrera/main.c @@ -47,7 +47,7 @@ main(void) serialinit(); vecinit(); screeninit(); - print("\n\nBrazil\n"); + iprint("\n\nBrazil\n"); pageinit(); procinit0(); initseg(); @@ -137,6 +137,8 @@ machinit(void) /* scrub cache */ cleancache(); + memset(m, 0, sizeof(Mach)); + n = m->machno; m->stb = &stlb[n][0]; @@ -374,7 +376,7 @@ confinit(void) conf.npage1 = 0; conf.base1 = 0; - conf.upages = (conf.npage*50)/100; + conf.upages = (conf.npage*70)/100; conf.nmach = 1; diff --git a/carrera/trap.c b/carrera/trap.c index f0031645ecc804e6d5b916f09db9cb28ccfec111..1c7a1e159e6757615d260bf1c552ef5bc90acafb 100644 --- a/carrera/trap.c +++ b/carrera/trap.c @@ -406,6 +406,7 @@ dumpregs(Ureg *ur) else print("registers for kernel\n"); + l = &ur->status; for(i=0; i 0; i++) { + for(i = 0; i < NFILE; i++) { m->next = m+1; m->prev = m-1; m++; @@ -95,13 +95,14 @@ clook(Chan *c) } void -cprint(Mntcache *m) +cprint(Mntcache *m, char *s) { Extent *e; +return; + print("%s: 0x%lux.0x%lux %d %d\n", + s, m->path, m->vers, m->type, m->dev); - print("%lux.%lux %d %d\n", m->path, m->vers, m->type, m->dev); - - while(e) + for(e = m->list; e; e = e->next) print("\t%4d %5d %4d %lux\n", e->bid, e->start, e->len, e->cache); } @@ -129,12 +130,14 @@ cnodata(Mntcache *m) n = e->next; free(e); } + m->list = 0; } void -ctail(Mntcache *m) +ctail(Mntcache *m, int dolock) { - lock(&cache); + if(dolock) + lock(&cache); /* Unlink and send to the tail */ if(m->prev) @@ -157,7 +160,8 @@ ctail(Mntcache *m) m->prev = m->next = 0; } - unlock(&cache); + if(dolock) + unlock(&cache); } void @@ -165,14 +169,22 @@ copen(Chan *c) { Mntcache *m, *f, **l; + if(c->qid.path & CHDIR) + return; + m = clook(c); if(m != 0) { + c->mcp = m; + ctail(m, 1); + /* File was updated */ - if(m->vers != c->qid.vers) + if(m->vers != c->qid.vers) { +cprint(m, "copen mod"); cnodata(m); - - ctail(m); + m->vers = c->qid.vers; + } qunlock(m); +cprint(m, "copen lru"); return; } @@ -191,14 +203,16 @@ copen(Chan *c) l = &cache.hash[c->qid.path%NHASH]; m->hash = *l; *l = m; + ctail(m, 0); unlock(&cache); + m->Qid = c->qid; m->dev = c->dev; m->type = c->type; cnodata(m); - ctail(m); c->mcp = m; qunlock(m); +cprint(m, "copen new"); } static int @@ -224,9 +238,13 @@ cread(Chan *c, uchar *buf, int len, ulong offset) Extent *e, **t; int o, l, total, end; + if(c->qid.path & CHDIR) + return 0; + m = c->mcp; if(m == 0) return 0; + qlock(m); if(cdev(m, c) == 0) { qunlock(m); @@ -306,12 +324,13 @@ cchain(uchar *buf, ulong offset, int len, Extent **tail) free(e); break; } - e->cache = p; - e->start = offset; l = len; if(l > BY2PG) l = BY2PG; + e->cache = p; + e->start = offset; + e->len = l; e->bid = incref(&cache); p->daddr = e->bid; k = kmap(p); @@ -341,6 +360,7 @@ cpgmove(Extent *e, uchar *buf, int boff, int len) p = cpage(e); if(p == 0) return 0; + k = kmap(p); memmove((uchar*)VA(k)+boff, buf, len); kunmap(k); @@ -355,9 +375,12 @@ cupdate(Chan *c, uchar *buf, int len, ulong offset) Mntcache *m; Extent *tail; Extent *e, *f, *p; - int o, ee, eblock; + int o, ee, eblock; - if(offset > MAXCACHE) + if(c->qid.path & CHDIR) + return; + + if(offset > MAXCACHE || len == 0) return; m = c->mcp; @@ -378,6 +401,7 @@ cupdate(Chan *c, uchar *buf, int len, ulong offset) break; p = f; } + if(p == 0) { /* at the head */ eblock = offset+len; /* trim if there is a successor */ @@ -418,8 +442,8 @@ cupdate(Chan *c, uchar *buf, int len, ulong offset) qunlock(m); return; } - if(cpgmove(e, buf, p->len, o)) { - e->len += o; + if(cpgmove(p, buf, p->len, o)) { + p->len += o; buf += o; len -= o; offset += o; @@ -448,7 +472,7 @@ cupdate(Chan *c, uchar *buf, int len, ulong offset) len -= o; } - /* Insert a middle block */ + /* insert a middle block */ p->next = cchain(buf, offset, len, &tail); if(p->next == 0) p->next = f; @@ -457,3 +481,62 @@ cupdate(Chan *c, uchar *buf, int len, ulong offset) qunlock(m); } + +void +cwrite(Chan* c, uchar *buf, int len, ulong offset) +{ + int o; + Mntcache *m; + ulong eblock, ee; + Extent *p, *f, *e, *tail; + + if(offset > MAXCACHE || len == 0) + return; + + m = c->mcp; + if(m == 0) + return; + + qlock(m); + if(cdev(m, c) == 0) { + qunlock(m); + return; + } + + m->vers++; + + p = 0; + for(f = m->list; f; f = f->next) { + if(offset >= f->start) + break; + p = f; + } + + if(p != 0) { + ee = p->start+p->len; + if(ee > offset) { + o = ee - offset; + p->len -= o; + if(p->len) + panic("del empty extent"); + } + } + + eblock = offset+len; + /* free the overlap - its a rare case */ + while(f && f->start < eblock) { + e = f->next; + free(f); + f = e; + } + + e = cchain(buf, offset, len, &tail); + if(p == 0) + m->list = e; + else + p->next = e; + if(tail != 0) + tail->next = f; + qunlock(m); +cprint(m, "cwrite"); +} diff --git a/port/chan.c b/port/chan.c index d201d77dcc7e8449a8cbbd97aad109e96ee2b601..83a7d381a95ff67d1b64fca11fb7b3e45b49673a 100644 --- a/port/chan.c +++ b/port/chan.c @@ -141,13 +141,6 @@ close(Chan *c) poperror(); } -/* ASSERT */ -if(c->path && c->path->ref == 0) { - char buf[64]; - ptpath(c->path, buf, sizeof(buf)); - print(">>%s %c %d %lux.%lux\n", - buf, devchar[c->type], c->dev, c->qid.path, c->qid.vers); -} chanfree(c); } diff --git a/port/devmnt.c b/port/devmnt.c index ebaaad59114bc56072c37bfecb0bbb4f7adbfb6a..1bcd57a693d703e41f1b2e19c426de10d38446e7 100644 --- a/port/devmnt.c +++ b/port/devmnt.c @@ -66,6 +66,8 @@ mntreset(void) { mntalloc.id = 1; mntalloc.rpctag = Tagspace; + + cinit(); } void @@ -83,7 +85,7 @@ mntattach(char *muxattach) struct bogus{ Chan *chan; char *spec; - int flag; + int flags; }bogus; bogus = *((struct bogus *)muxattach); @@ -91,7 +93,7 @@ mntattach(char *muxattach) lock(&mntalloc); for(m = mntalloc.list; m; m = m->list) { - if(m->c == c && m->id) { + if(m->c == c && m->id && m->flags == bogus.flags) { lock(m); if(m->id && m->ref > 0 && m->c == c) { unlock(&mntalloc); @@ -109,6 +111,7 @@ mntattach(char *muxattach) unlock(m); } } + m = mntalloc.mntfree; if(m != 0) mntalloc.mntfree = m->list; @@ -354,6 +357,10 @@ mntopen(Chan *c, int omode) c->flag |= COPEN; poperror(); mntfree(r); + + if(m->flags&MCACHE) + copen(c); + return c; } @@ -381,6 +388,9 @@ mntcreate(Chan *c, char *name, int omode, ulong perm) c->mode = openmode(omode); poperror(); mntfree(r); + + if(m->flags & MCACHE) + copen(c); } void @@ -481,19 +491,21 @@ mntwstat(Chan *c, char *dp) long mntread(Chan *c, void *buf, long n, ulong offset) { - int nc; + Mnt *m; uchar *p, *e; + int nc, cached; m = mntchk(c); - nc = 0; - if((m->flags&MCACHE) && !isdir(c)) { - nc = cread(c, buf, n, offset); - if(nc == n) - return n; + cached = m->flags&MCACHE; - buf = (uchar*)buf+nc; - offset += nc; - n -= nc; + SET(nc); + if(cached) { + nc = cread(c, buf, n, offset); + if(nc > 0) { + buf = (uchar*)buf+nc; + offset += nc; + n -= nc; + } } n = mntrdwr(Tread, m, c, buf, n, offset); @@ -501,8 +513,10 @@ mntread(Chan *c, void *buf, long n, ulong offset) for(p = (uchar*)buf, e = &p[n]; p < e; p += DIRLEN) mntdirfix(p, c); - if(nc != 0) + if(cached) { cupdate(c, buf, n, offset); + n += nc; + } return n; } @@ -510,8 +524,7 @@ mntread(Chan *c, void *buf, long n, ulong offset) long mntwrite(Chan *c, void *buf, long n, ulong offset) { - m = mntchk(c); - return mntrdwr(Twrite, m, c, buf, n, offset); + return mntrdwr(Twrite, mntchk(c), c, buf, n, offset); } long @@ -519,10 +532,12 @@ mntrdwr(int type, Mnt *m, Chan *c, void *buf, long n, ulong offset) { Mntrpc *r; char *uba; + int cache; ulong cnt, nr; uba = buf; cnt = 0; + cache = m->flags & MCACHE; for(;;) { r = mntralloc(c); if(waserror()) { @@ -538,8 +553,12 @@ mntrdwr(int type, Mnt *m, Chan *c, void *buf, long n, ulong offset) nr = r->reply.count; if(nr > r->request.count) nr = r->request.count; + if(type == Tread) memmove(uba, r->reply.data, nr); + else if(cache) + cwrite(c, (uchar*)r->reply.data, nr, offset); + poperror(); mntfree(r); offset += nr; diff --git a/port/page.c b/port/page.c index a9baaea278ecec1ed5af3efb9dd0e8b3474c7670..46380dc1bd6bfe48b4efa6da7b0b070d4456e461 100644 --- a/port/page.c +++ b/port/page.c @@ -218,6 +218,33 @@ putpage(Page *p) unlock(p); } +Page* +auxpage() +{ + Page *p; + + lock(&palloc); + p = palloc.head; + if(palloc.freecol[p->color] < swapalloc.highwater/NCOLOR) { + unlock(&palloc); + return 0; + } + p->next->prev = 0; + palloc.head = p->next; + palloc.freecol[p->color]--; + unlock(&palloc); + + lock(p); + if(p->ref != 0) { /* Stolen by lookpage */ + unlock(p); + return 0; + } + p->ref++; + uncachepage(p); + unlock(p); + return p; +} + void duppage(Page *p) /* Always call with p locked */ { @@ -322,6 +349,7 @@ uncachepage(Page *p) /* Always called with a locked page */ unlock(&palloc.hashlock); putimage(p->image); p->image = 0; + p->daddr = 0; } void diff --git a/port/portfns.h b/port/portfns.h index 9f54c151b3d9ba8d3e1758630caeb3734a56ceb5..7ac65db57d346da3d465ec2364c58b6b39842d94 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -277,3 +277,6 @@ Segment* seg(Proc*, ulong, int); int cread(Chan*, uchar*, int, ulong); void cupdate(Chan*, uchar*, int, ulong); +void cwrite(Chan*, uchar*, int, ulong); +void copen(Chan*); +void cinit(void); diff --git a/power/dat.h b/power/dat.h index e3d632ff81bca1c885e4b936c604cbeffedd8e7f..236c455203d17b4f1141a4cca4df778e1aff03cb 100644 --- a/power/dat.h +++ b/power/dat.h @@ -8,6 +8,7 @@ typedef struct Label Label; typedef struct Lock Lock; typedef struct Mach Mach; typedef struct MMU MMU; +typedef struct Notsave Notsave; typedef struct PMMU PMMU; typedef struct Softtlb Softtlb; typedef struct Ureg Ureg; @@ -84,6 +85,15 @@ struct PMMU Cycmsg *fcyc; }; +/* + * things saved in the Proc structure during a notify + */ +struct Notsave +{ + ulong svstatus; + ulong svr1; +}; + #include "../port/portdat.h" struct Cycmsg