M carrera/main.c => carrera/main.c +4 -2
@@ 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;
M carrera/trap.c => carrera/trap.c +1 -0
@@ 406,6 406,7 @@ dumpregs(Ureg *ur)
else
print("registers for kernel\n");
+
l = &ur->status;
for(i=0; i<sizeof regname/sizeof(char*); i+=2, l+=2)
print("%s\t0x%.8lux\t%s\t0x%.8lux\n", regname[i], l[0], regname[i+1], l[1]);
M port/cache.c => port/cache.c +102 -19
@@ 58,7 58,7 @@ cinit(void)
cache.head = xalloc(sizeof(Mntcache)*NFILE);
m = cache.head;
- for(i = NFILE; 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");
+}
M port/chan.c => port/chan.c +0 -7
@@ 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);
}
M port/devmnt.c => port/devmnt.c +33 -14
@@ 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;
M port/page.c => port/page.c +28 -0
@@ 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
M port/portfns.h => port/portfns.h +3 -0
@@ 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);
M power/dat.h => power/dat.h +10 -0
@@ 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