From d94140b5c6daf32bfac211d9ed602ce06d1c13b7 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 22 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-22 --- gnot/dat.h | 4 - gnot/main.c | 27 +-- gnot/mem.h | 1 + gnot/mmu.c | 4 +- pc/dat.h | 4 - pc/main.c | 4 - port/alloc.c | 20 +- port/devbit.c | 582 ++++++++++++++++++++++++++--------------------- port/devconc.c | 2 +- port/devdk.c | 52 ++--- port/devenv.c | 2 +- port/devip.c | 8 +- port/devmux.c | 2 +- port/devscc.c | 4 +- port/devsrv.c | 143 +++++++----- port/error.h | 2 +- port/page.c | 2 +- port/portfns.h | 500 ++++++++++++++++++++-------------------- port/proc.c | 4 +- port/stasync.c | 14 +- port/stip.c | 2 +- port/stlapd.c | 63 ++--- port/sturp.c | 2 +- port/sysproc.c | 111 +-------- port/systab.h | 12 +- power/conf.h | 13 -- power/dat.h | 16 +- power/devcyc.c | 1 - power/devduart.c | 6 +- power/fns.h | 2 + power/lock.c | 138 +++++------ power/main.c | 76 ++----- power/mem.h | 1 + ss/main.c | 7 +- 34 files changed, 845 insertions(+), 986 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index b6be40bb51311c1819436e550449f2ac0244a3bf..479142464098640dbe310e2ef5746b9159c0095f 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -83,10 +83,6 @@ struct Conf int nstream; /* streams */ int nqueue; /* stream queues */ int nsrv; /* public servers (devsrv.c) */ - int nbitmap; /* bitmap structs (devbit.c) */ - int nbitbyte; /* bytes of bitmap data (devbit.c) */ - int nfont; /* GFont structs (devbit.c) */ - int nsubfont; /* Gsubfont structs (devbit.c) */ int nurp; /* max urp conversations */ int nasync; /* number of async protocol modules */ int nfsyschan; /* number of filsys open channels */ diff --git a/gnot/main.c b/gnot/main.c index 5d0f7f0dae1b665f807d7dfc587d31dffd0c90c1..c6242093bcca767165e04a4fdfc8b294bef3e64c 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -52,8 +52,6 @@ main(void) chaninit(); chandevreset(); streaminit(); -/* serviceinit(); /**/ -/* filsysinit(); /**/ swapinit(); pageinit(); kmapinit(); @@ -278,19 +276,19 @@ banksize(int base) if(end > (char *)((KZERO|1024L*1024L)-BY2PG)) return 0; va = UZERO; /* user page 1 is free to play with */ - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); *(ulong*)va = 0; /* 0 at 0M */ - putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+1)*MB/BY2PG, 0); *(ulong*)va = 1; /* 1 at 1M */ - putmmu(va, PTEVALID|(base+4)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+4)*MB/BY2PG, 0); *(ulong*)va = 4; /* 4 at 4M */ - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); if(*(ulong*)va == 0) return 16; - putmmu(va, PTEVALID|(base+1)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+1)*MB/BY2PG, 0); if(*(ulong*)va == 1) return 4; - putmmu(va, PTEVALID|(base+0)*1024L*1024L/BY2PG, 0); + putmmu(va, PTEVALID|(base+0)*MB/BY2PG, 0); if(*(ulong*)va == 4) return 1; return 0; @@ -307,10 +305,10 @@ confinit(void) panic("confinit"); bank[0] = banksize(0); bank[1] = banksize(16); - conf.npage0 = (bank[0]*1024*1024)/BY2PG; + conf.npage0 = (bank[0]*MB)/BY2PG; conf.base0 = 0; - conf.npage1 = (bank[1]*1024*1024)/BY2PG; - conf.base1 = 16*1024*1024; + conf.npage1 = (bank[1]*MB)/BY2PG; + conf.base1 = 16*MB; conf.npage = conf.npage0+conf.npage1; conf.upages = (conf.npage*70)/100; @@ -323,14 +321,7 @@ confinit(void) conf.npgenv = 200*mul; conf.nstream = 40 + 32*mul; conf.nqueue = 5 * conf.nstream; - conf.nsrv = 16*mul; /* was 32 */ - conf.nbitmap = 300*mul; - conf.nbitbyte = 300*1024*mul; conf.nmux = 10; - if(*(uchar*)MOUSE & (1<<4)) - conf.nbitbyte *= 2; /* ldepth 1 */ - conf.nsubfont = 30*mul; - conf.nfont = 10*mul; conf.nurp = 32; conf.nasync = 1; conf.copymode = 0; /* copy on write */ diff --git a/gnot/mem.h b/gnot/mem.h index fef61b8028c16b44d7f2ee90f2c02b379a3a0f3b..0d6523f01e44863e169c83f9beb202a9cf4d1769 100644 --- a/gnot/mem.h +++ b/gnot/mem.h @@ -15,6 +15,7 @@ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) #define ICACHESIZE 0 #define MB4 (4*1024*1024) /* Lots of things are 4Mb in size */ +#define MB (1024*1024) #define MAXMACH 1 /* max # cpus system can run */ diff --git a/gnot/mmu.c b/gnot/mmu.c index 7be34514b3f14dd22a4fa4336a8c05a3f7a06eea..6081ebe4983121c4f4b6b785c4db0d5606916140 100644 --- a/gnot/mmu.c +++ b/gnot/mmu.c @@ -99,9 +99,9 @@ kmapinit(void) print("%lud free map registers\n", e-i); kmapalloc.free = 0; - for(k=&kmapalloc.arena[i]; iva = i*BY2PG|KZERO; - kunmap(k); + kunmap(k++); } } diff --git a/pc/dat.h b/pc/dat.h index 3ac8d3c731515e9300a58b763d70a099a671010e..98f281fba1fdc81d8c4b4a804e436b5cf0af6646 100644 --- a/pc/dat.h +++ b/pc/dat.h @@ -74,10 +74,6 @@ struct Conf ulong nqueue; /* stream queues */ ulong nblock; /* stream blocks */ ulong nsrv; /* public servers (devsrv.c) */ - ulong nbitmap; /* bitmap structs (devbit.c) */ - ulong nbitbyte; /* bytes of bitmap data (devbit.c) */ - int nfont; /* GFont structs (devbit.c) */ - ulong nsubfont; /* Gsubfont structs (devbit.c) */ ulong nurp; /* max urp conversations */ ulong nasync; /* number of async protocol modules */ ulong npipe; /* number of pipes */ diff --git a/pc/main.c b/pc/main.c index bd7a6768dd46f79ea3f39bbea2cb51f92def4f64..c3ef01765fc6bf8fe940abff1faf7af1f36863b4 100644 --- a/pc/main.c +++ b/pc/main.c @@ -259,10 +259,6 @@ confinit(void) conf.nmntbuf = conf.nmntdev+3; conf.nmnthdr = 2*conf.nmntdev; conf.nsrv = 16*mul; /* was 32 */ - conf.nbitmap = 512*mul; - conf.nbitbyte = conf.nbitmap*1024*screenbits(); - conf.nfont = 10*mul; - conf.nsubfont = 30*mul; conf.nurp = 32; conf.nasync = 1; conf.nstream = (conf.nproc*3)/2; diff --git a/port/alloc.c b/port/alloc.c index 56b5b224d48bc3016f11f47a3aacee001d25f748..341d594adadeb6fcf45d9153f40fb604a0ed1109 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -73,21 +73,6 @@ struct Arena static Arena arena; static Xalloc xlists; -void* -ialloc(ulong size, int align) -{ - ulong p; - - if(align) { - size += BY2PG; - p = (ulong)xalloc(size); - p += BY2PG; - p &= ~(BY2PG-1); - return (void*)p; - } - return xalloc(size);; -} - void xinit(void) { @@ -305,8 +290,11 @@ smalloc(ulong size) void *p; p = malloc(size); - if(p == nil) + if(p == nil) { + print("asking for %d\n", size); + xsummary(); panic("smalloc should sleep"); + } return p; } diff --git a/port/devbit.c b/port/devbit.c index fa0c9bd554c9823dd973214ae8d0b418c67dfa73..a0909bbcaf4a82eb86ebe65f075c71f87058871b 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -37,26 +37,36 @@ int flipping; /* are flip tables being used to transform Fcodes? */ */ /* - * Arena is a word containing N, followed by a pointer to its bitmap, - * followed by N blocks. The bitmap pointer is zero if block is free. + * Arena is a word containing N, followed by a pointer to the Arena, + * followed by a pointer to the Bitmap, followed by N words. + * The bitmap pointer is zero if block is free. * bit.map is an array of pointers to GBitmaps. The GBitmaps are * freed individually and their corresponding entries in bit.map are zeroed. * The index into bit.map is the Bitmap id as seen in libg. Subfonts and * fonts are handled similarly. */ +typedef struct Arena Arena; +struct Arena +{ + ulong *words; /* storage */ + ulong *wfree; /* pointer to next free word */ + ulong nwords; /* total in arena */ + int nbusy; /* number of busy blocks */ +}; + struct { Ref; + QLock; GBitmap **map; /* indexed array */ int nmap; /* number allocated */ - ulong *words; /* storage */ - ulong nwords; /* total in arena */ - ulong *wfree; /* pointer to next free word */ GFont **font; /* indexed array */ int nfont; /* number allocated */ GSubfont**subfont; /* indexed array */ int nsubfont; /* number allocated */ + Arena *arena; /* array */ + int narena; /* number allocated */ int lastid; /* last allocated bitmap id */ int lastsubfid; /* last allocated subfont id */ int lastfid; /* last allocated font id */ @@ -67,13 +77,15 @@ struct int mid; /* colormap read bitmap id */ }bit; -#define DMAP 32 /* delta increase in size of arrays */ +#define DMAP 16 /* delta increase in size of arrays */ #define FREE 0x80000000 + void bitcompact(void); int bitalloc(Rectangle, int); void bitfree(GBitmap*); void fontfree(GFont*); void subfontfree(GSubfont*); +void arenafree(Arena*); void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode); void bitloadchar(GFont*, int, GSubfont*, int); extern GBitmap gscreen; @@ -149,6 +161,7 @@ Dirtab bitdir[]={ #define NBIT (sizeof bitdir/sizeof(Dirtab)) #define NINFO 8192 +#define HDR 3 void bitreset(void) @@ -156,6 +169,7 @@ bitreset(void) int i; GBitmap *bp; ulong r; + Arena *a; bit.map = smalloc(DMAP*sizeof(GBitmap*)); bit.nmap = DMAP; @@ -165,14 +179,23 @@ bitreset(void) bit.lastid = -1; bit.lastsubfid = -1; bit.lastfid = -1; - bit.words = ialloc(conf.nbitbyte, 0); -print("bitreset %lux\n", bit.words); - bit.nwords = conf.nbitbyte/sizeof(ulong); - bit.wfree = bit.words; bit.font = smalloc(DMAP*sizeof(GFont*)); bit.nfont = DMAP; bit.subfont = smalloc(DMAP*sizeof(GSubfont*)); bit.nsubfont = DMAP; + bit.arena = smalloc(DMAP*sizeof(Arena)); + bit.narena = DMAP; + a = &bit.arena[0]; + /* + * Somewhat of a heuristic: start with three screensful and + * allocate single screensful dynamically if needed. + */ + a->nwords = 3*(gscreen.width*gscreen.r.max.y+HDR); + a->words = xalloc(a->nwords*sizeof(ulong)); + if(a->words == 0) + panic("bitreset"); + a->wfree = a->words; + a->nbusy = 1; /* keep 0th arena from being freed */ Cursortocursor(&arrow); } @@ -336,8 +359,7 @@ bitread(Chan *c, void *va, long n, ulong offset) if(c->qid.path & CHDIR) return devdirread(c, va, n, bitdir, NBIT, devgen); - switch(c->qid.path){ - case Qmouse: + if(c->qid.path == Qmouse){ /* * mouse: * 'm' 1 @@ -361,179 +383,9 @@ bitread(Chan *c, void *va, long n, ulong offset) PLONG(p+6, mouse.xy.y); mouse.changed = 0; unlock(&cursor); - n = 10; - break; - - case Qbitblt: - p = va; - /* - * Fuss about and figure out what to say. - */ - if(bit.init){ - /* - * init: - * 'I' 1 - * ldepth 1 - * rectangle 16 - * if count great enough, also - * font info 3*12 - * fontchars 6*(defont->n+1) - */ - if(n < 18) - error(Ebadblt); - p[0] = 'I'; - p[1] = gscreen.ldepth; - PLONG(p+2, gscreen.r.min.x); - PLONG(p+6, gscreen.r.min.y); - PLONG(p+10, gscreen.r.max.x); - PLONG(p+14, gscreen.r.max.y); - dn = 18; - if(bit.init=='j' && n>=18+16){ - PLONG(p+18, gscreen.clipr.min.x); - PLONG(p+22, gscreen.clipr.min.y); - PLONG(p+26, gscreen.clipr.max.x); - PLONG(p+30, gscreen.clipr.max.y); - dn += 16; - } - if(n >= dn+3*12+6*(defont->n+1)){ - p += dn; - sprint((char*)p, "%11d %11d %11d ", defont->n, - defont->height, defont->ascent); - p += 3*12; - for(i=defont->info,j=0; j<=defont->n; j++,i++,p+=6){ - PSHORT(p, i->x); - p[2] = i->top; - p[3] = i->bottom; - p[4] = i->left; - p[5] = i->width; - } - n = dn+3*12+6*(defont->n+1); - }else - n = dn; - bit.init = 0; - break; - } - if(bit.lastid > 0){ - /* - * allocate: - * 'A' 1 - * bitmap id 2 - */ - if(n < 3) - error(Ebadblt); - p[0] = 'A'; - PSHORT(p+1, bit.lastid); - bit.lastid = -1; - n = 3; - break; - } - if(bit.lastsubfid > 0){ - /* - * allocate subfont: - * 'K' 1 - * subfont id 2 - */ - if(n < 3) - error(Ebadblt); - p[0] = 'K'; - PSHORT(p+1, bit.lastsubfid); - bit.lastsubfid = -1; - n = 3; - break; - } - if(bit.lastfid >= 0){ - /* - * allocate font: - * 'N' 1 - * font id 2 - */ - if(n < 3) - error(Ebadblt); - p[0] = 'N'; - PSHORT(p+1, bit.lastfid); - bit.lastfid = -1; - n = 3; - break; - } - if(bit.mid >= 0){ - /* - * read colormap: - * data 12*(2**bitmapdepth) - */ - src = bit.map[bit.mid]; - if(src == 0) - error(Ebadbitmap); - l = (1<ldepth); - nw = 1 << l; - if(n < 12*nw) - error(Ebadblt); - for(j = 0; j < nw; j++){ - if(bit.mid == 0){ - getcolor(flipping? ~j : j, &rv, &gv, &bv); - }else{ - rv = j; - for(off = 32-l; off > 0; off -= l) - rv = (rv << l) | j; - gv = bv = rv; - } - PLONG(p, rv); - PLONG(p+4, gv); - PLONG(p+8, bv); - p += 12; - } - bit.mid = -1; - n = 12*nw; - break; - } - if(bit.rid >= 0){ - /* - * read bitmap: - * data bytewidth*(maxy-miny) - */ - src = bit.map[bit.rid]; - if(src == 0) - error(Ebadbitmap); - off = 0; - if(bit.rid == 0) - off = 1; - miny = bit.rminy; - maxy = bit.rmaxy; - if(miny>maxy || minyr.min.y || maxy>src->r.max.y) - error(Ebadblt); - ws = 1<<(3-src->ldepth); /* pixels per byte */ - /* set l to number of bytes of incoming data per scan line */ - if(src->r.min.x >= 0) - l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; - else{ /* make positive before divide */ - t = (-src->r.min.x)+ws-1; - t = (t/ws)*ws; - l = (t+src->r.max.x+ws-1)/ws; - } - if(n < l*(maxy-miny)) - error(Ebadblt); - if(off) - cursoroff(1); - n = 0; - p = va; - for(y=miny; yr.min.x, y)); - q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; - if(bit.rid == 0 && flipping) /* flip bits */ - for(x=0; xqid.path == Qscreen){ if(offset==0){ if(n < 5*12) error(Eio); @@ -541,8 +393,7 @@ bitread(Chan *c, void *va, long n, ulong offset) gscreen.ldepth, gscreen.r.min.x, gscreen.r.min.y, gscreen.r.max.x, gscreen.r.max.y); - n = 5*12; - break; + return 5*12; } ws = 1<<(3-gscreen.ldepth); /* pixels per byte */ l = (gscreen.r.max.x+ws-1)/ws - gscreen.r.min.x/ws; @@ -565,12 +416,174 @@ bitread(Chan *c, void *va, long n, ulong offset) *p++ = *q++; n += l; } - break; - - default: + return n; + } + if(c->qid.path != Qbitblt) error(Egreg); + + qlock(&bit); + if(waserror()){ + qunlock(&bit); + nexterror(); + } + p = va; + /* + * Fuss about and figure out what to say. + */ + if(bit.init){ + /* + * init: + * 'I' 1 + * ldepth 1 + * rectangle 16 + * if count great enough, also + * font info 3*12 + * fontchars 6*(defont->n+1) + */ + if(n < 18) + error(Ebadblt); + p[0] = 'I'; + p[1] = gscreen.ldepth; + PLONG(p+2, gscreen.r.min.x); + PLONG(p+6, gscreen.r.min.y); + PLONG(p+10, gscreen.r.max.x); + PLONG(p+14, gscreen.r.max.y); + dn = 18; + if(bit.init=='j' && n>=18+16){ + PLONG(p+18, gscreen.clipr.min.x); + PLONG(p+22, gscreen.clipr.min.y); + PLONG(p+26, gscreen.clipr.max.x); + PLONG(p+30, gscreen.clipr.max.y); + dn += 16; + } + if(n >= dn+3*12+6*(defont->n+1)){ + p += dn; + sprint((char*)p, "%11d %11d %11d ", defont->n, + defont->height, defont->ascent); + p += 3*12; + for(i=defont->info,j=0; j<=defont->n; j++,i++,p+=6){ + PSHORT(p, i->x); + p[2] = i->top; + p[3] = i->bottom; + p[4] = i->left; + p[5] = i->width; + } + n = dn+3*12+6*(defont->n+1); + }else + n = dn; + bit.init = 0; + }else if(bit.lastid > 0){ + /* + * allocate: + * 'A' 1 + * bitmap id 2 + */ + if(n < 3) + error(Ebadblt); + p[0] = 'A'; + PSHORT(p+1, bit.lastid); + bit.lastid = -1; + n = 3; + }else if(bit.lastsubfid > 0){ + /* + * allocate subfont: + * 'K' 1 + * subfont id 2 + */ + if(n < 3) + error(Ebadblt); + p[0] = 'K'; + PSHORT(p+1, bit.lastsubfid); + bit.lastsubfid = -1; + n = 3; + }else if(bit.lastfid >= 0){ + /* + * allocate font: + * 'N' 1 + * font id 2 + */ + if(n < 3) + error(Ebadblt); + p[0] = 'N'; + PSHORT(p+1, bit.lastfid); + bit.lastfid = -1; + n = 3; + }else if(bit.mid >= 0){ + /* + * read colormap: + * data 12*(2**bitmapdepth) + */ + src = bit.map[bit.mid]; + if(src == 0) + error(Ebadbitmap); + l = (1<ldepth); + nw = 1 << l; + if(n < 12*nw) + error(Ebadblt); + for(j = 0; j < nw; j++){ + if(bit.mid == 0){ + getcolor(flipping? ~j : j, &rv, &gv, &bv); + }else{ + rv = j; + for(off = 32-l; off > 0; off -= l) + rv = (rv << l) | j; + gv = bv = rv; + } + PLONG(p, rv); + PLONG(p+4, gv); + PLONG(p+8, bv); + p += 12; + } + bit.mid = -1; + n = 12*nw; + }else if(bit.rid >= 0){ + /* + * read bitmap: + * data bytewidth*(maxy-miny) + */ + src = bit.map[bit.rid]; + if(src == 0) + error(Ebadbitmap); + off = 0; + if(bit.rid == 0) + off = 1; + miny = bit.rminy; + maxy = bit.rmaxy; + if(miny>maxy || minyr.min.y || maxy>src->r.max.y) + error(Ebadblt); + ws = 1<<(3-src->ldepth); /* pixels per byte */ + /* set l to number of bytes of incoming data per scan line */ + if(src->r.min.x >= 0) + l = (src->r.max.x+ws-1)/ws - src->r.min.x/ws; + else{ /* make positive before divide */ + t = (-src->r.min.x)+ws-1; + t = (t/ws)*ws; + l = (t+src->r.max.x+ws-1)/ws; + } + if(n < l*(maxy-miny)) + error(Ebadblt); + if(off) + cursoroff(1); + n = 0; + p = va; + for(y=miny; yr.min.x, y)); + q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws; + if(bit.rid == 0 && flipping) /* flip bits */ + for(x=0; x=bit.nmap || (dst=bit.map[v])==0) - error(Ebadbitmap); - off = 0; - fc = GSHORT(p+13) & 0xF; - if(v == 0){ - if(flipping) - fc = flipD[fc]; - off = 1; - } - pt.x = GLONG(p+3); - pt.y = GLONG(p+7); - v = GSHORT(p+11); - if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0) - error(Ebadblt); - p += 15; - m -= 15; - q = memchr(p, 0, m); - if(q == 0) - error(Ebadblt); - if(off && !isoff){ - cursoroff(1); - isoff = 1; - } - gsubfstring(dst, pt, f, (char*)p, fc); - q++; - m -= q-p; - p = q; - break; - case 't': /* * texture @@ -1234,13 +1207,13 @@ bitwrite(Chan *c, void *va, long n, ulong offset) if(m < 9) error(Ebadblt); v = GSHORT(p+1); - if(v<0 || v>=conf.nfont || (ff=bit.font[v])==0) + if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0) error(Ebadblt); l = GSHORT(p+3); if(l >= NFCACHE+NFLOOK) error(Ebadblt); v = GSHORT(p+5); - if(v<0 || v>=conf.nsubfont || (f=bit.subfont[v])==0) + if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0) error(Ebadblt); nw = GSHORT(p+7); if(nw >= f->n) @@ -1286,18 +1259,19 @@ bitwrite(Chan *c, void *va, long n, ulong offset) poperror(); if(isoff) cursoron(1); + qunlock(&bit); return n; } int bitalloc(Rectangle rect, int ld) { + Arena *a, *ea, *na, *aa; GBitmap *b, **bp, **ep; ulong l, ws, nw; long t; - int i; + int i, try; -print("bitalloc %lux\n", bit.wfree); ws = 1<<(5-ld); /* pixels per word */ if(rect.min.x >= 0){ l = (rect.max.x+ws-1)/ws; @@ -1308,17 +1282,58 @@ print("bitalloc %lux\n", bit.wfree); l = (t+rect.max.x+ws-1)/ws; } nw = l*Dy(rect); - if(bit.wfree+2+nw > bit.words+bit.nwords){ - bitcompact(); - if(bit.wfree+2+nw > bit.words+bit.nwords) - error(Enobitstore); + ea = &bit.arena[bit.narena]; + + /* first try easy fit */ + for(a=bit.arena; awords == 0) + continue; + if(a->wfree+HDR+nw <= a->words+a->nwords) + goto found; } + + /* compact and try again */ + bitcompact(); + aa = 0; + for(a=bit.arena; awords == 0){ + if(aa == 0) + aa = a; + continue; + } + if(a->wfree+HDR+nw <= a->words+a->nwords) + goto found; + } + + /* need new arena */ + if(aa) + a = aa; + else{ + na = bit.arena; + bit.arena = smalloc((bit.narena+DMAP)*sizeof(Arena)); + memmove(bit.arena, na, bit.narena*sizeof(Arena)); + free(na); + a = bit.arena+bit.narena; + bit.narena += DMAP; + } + a->nwords = gscreen.width*gscreen.r.max.y+HDR; + if(a->nwords < HDR+nw) + a->nwords = HDR+nw; + a->words = xalloc(a->nwords*sizeof(ulong)); + if(a->words == 0) + error(Enobitstore); + a->wfree = a->words; + a->nbusy = 0; + + found: b = smalloc(sizeof(GBitmap)); - *bit.wfree++ = nw; - *bit.wfree++ = (ulong)b; - b->base = bit.wfree; + *a->wfree++ = nw; + *a->wfree++ = (ulong)a; + *a->wfree++ = (ulong)b; + b->base = a->wfree; memset(b->base, 0, nw*sizeof(ulong)); - bit.wfree += nw; + a->wfree += nw; + a->nbusy++; b->zero = l*rect.min.y; if(rect.min.x >= 0) b->zero += rect.min.x/ws; @@ -1350,6 +1365,12 @@ print("bitalloc %lux\n", bit.wfree); void bitfree(GBitmap *b) { + Arena *a; + + a = (Arena*)(b->base[-2]); + a->nbusy--; + if(a->nbusy == 0) + arenafree(a); b->base[-1] = 0; free(b); } @@ -1369,6 +1390,13 @@ subfontfree(GSubfont *s) free(s); } +void +arenafree(Arena *a) +{ + xfree(a->words); + a->words = 0; +} + void bitstring(GBitmap *bp, Point pt, GFont *f, uchar *p, long l, Fcode fc) { @@ -1435,29 +1463,65 @@ bitloadchar(GFont *f, int ci, GSubfont *subf, int si) gbitblt(f->b, Pt(c->x, f->ascent-subf->ascent), subf->bits, rect, S); } -QLock bitlock; - void bitcompact(void) { - ulong *p1, *p2; + Arena *a, *b, *ea, *na; + ulong *p1, *p2, n; - qlock(&bitlock); - p1 = p2 = bit.words; - while(p2 < bit.wfree){ - if(p2[1] == 0){ - p2 += 2 + p2[0]; + ea = &bit.arena[bit.narena]; + for(a=bit.arena; awords == 0) continue; + /* first compact what's here */ + p1 = p2 = a->words; + while(p2 < a->wfree){ + n = HDR+p2[0]; + if(p2[2] == 0){ + p2 += n; + continue; + } + if(p1 != p2){ + memmove(p1, p2, n*sizeof(ulong)); + ((GBitmap*)p1[2])->base = p1+HDR; + } + p2 += n; + p1 += n; } - if(p1 != p2){ - memmove(p1, p2, (2+p2[0])*sizeof(ulong)); - ((GBitmap*)p1[1])->base = p1+2; + /* now pull stuff from later arena to fill this one */ + na = a+1; + while(nawords+a->nwords){ + p2 = na->words; + if(p2 == 0){ + na++; + continue; + } + while(p2 < na->wfree){ + n = HDR+p2[0]; + if(p2[2] == 0){ + p2 += n; + continue; + } + if(p1+n < a->words+a->nwords){ + memmove(p1, p2, n*sizeof(ulong)); + ((GBitmap*)p1[2])->base = p1+HDR; + /* block now in new arena... */ + p1[1] = (ulong)a; + a->nbusy++; + /* ... not in old arena */ + na->nbusy--; + p2[2] = 0; + p1 += n; + } + p2 += n; + } + na++; } - p2 += 2 + p1[0]; - p1 += 2 + p1[0]; + a->wfree = p1; } - bit.wfree = p1; - qunlock(&bitlock); + for(a=bit.arena; awords; a++) + if(a->nbusy == 0) + arenafree(a); } void diff --git a/port/devconc.c b/port/devconc.c index 8a8a48869ed87fcfc487c29d0bf9ff944cdf6936..c27b37930c260fcbf834ff13929e7aa6e5a0d9b9 100644 --- a/port/devconc.c +++ b/port/devconc.c @@ -333,7 +333,7 @@ concdevstoput(Queue *q, Block *bp) void concreset(void) { - concs = ialloc(conf.nconc*sizeof(Conc), 0); + concs = xalloc(conf.nconc*sizeof(Conc)); newqinfo(&concinfo); } diff --git a/port/devdk.c b/port/devdk.c index c03ccd9bf17ceb91a7e579d3741bef8a7ebe3c0f..abe8a908ea475a2061bfb5181c9e1df329cd516a 100644 --- a/port/devdk.c +++ b/port/devdk.c @@ -159,14 +159,14 @@ enum { DKreject, }; char* dkerr[]={ - [DKok]"", - [DKbusy]"devdk: destination busy", - [DKnetotl]"devdk: network not answering", - [DKdestotl]"devdk: destination not answering", - [DKbadnet]"devdk: unknown address", - [DKnetbusy]"devdk: network busy", - [DKinuse]"devdk: service in use", - [DKreject]"devdk: connection refused", + [DKok] "", + [DKbusy] "devdk: destination busy", + [DKnetotl] "devdk: network not answering", + [DKdestotl] "devdk: destination not answering", + [DKbadnet] "devdk: unknown address", + [DKnetbusy] "devdk: network busy", + [DKinuse] "devdk: service in use", + [DKreject] "devdk: connection refused", }; #define DKERRS sizeof(dkerr)/sizeof(char*) @@ -229,7 +229,6 @@ dkalloc(char *name, int ncsc, int lines) { Dk *dp; Dk *freep; - Block *bp; int i, n; Line *lp; @@ -261,28 +260,15 @@ dkalloc(char *name, int ncsc, int lines) /* * allocate memory for line structures */ - n = sizeof(Line*)*(dp->lines); - bp = allocb(n); - if(bp->lim - bp->base < n){ - unlock(&dklock); - error(Ebadarg); - } - memset(bp->base, 0, bp->lim-bp->base); - dp->linep = (Line **)bp->base; - bp->wptr += n; - dp->alloc = bp; - n = sizeof(Line)*(dp->lines); - for(i = 0; i < dp->lines; i++){ - if(bp->lim - bp->wptr < sizeof(Line)){ - bp = allocb(sizeof(Line)*n); - memset(bp->base, 0, bp->lim-bp->base); - bp->next = dp->alloc; - dp->alloc = bp; - } - dp->linep[i] = (Line*)bp->wptr; - dp->linep[i]->lineno = i; - bp->wptr += sizeof(Line); - n -= sizeof(Line); + dp->linep = (Line **)xalloc(sizeof(Line*) * dp->lines); + if(dp->linep == 0) + error(Enomem); + lp = xalloc(dp->lines*sizeof(Line)); + if(lp == 0) + error(Enomem); + for(i = 0; i < dp->lines; i++) { + lp->lineno = i; + dp->linep[i] = lp++; } /* @@ -720,9 +706,9 @@ void dkreset(void) { int i; - dk = (Dk*)ialloc(conf.dkif*sizeof(Dk), 0); + dk = (Dk*)xalloc(conf.dkif*sizeof(Dk)); for(i = 0; i < conf.dkif; i++) - dk[i].prot = (Netprot*)ialloc(conf.nurp*sizeof(Netprot), 0); + dk[i].prot = (Netprot*)xalloc(conf.nurp*sizeof(Netprot)); newqinfo(&dkmuxinfo); } diff --git a/port/devenv.c b/port/devenv.c index 9ceaab5620e405d7d225fd3894f719d4981f9dac..ca50341c04e05f16d13dbe7d83ee7f08dffff249 100644 --- a/port/devenv.c +++ b/port/devenv.c @@ -42,7 +42,7 @@ void evfree(Envval*); void envreset(void) { - evscratch = ialloc(BY2PG, 0); + evscratch = xalloc(BY2PG); } void diff --git a/port/devip.c b/port/devip.c index f1230dbb8a9fe25092bb95187943d69069cf5137..05787c42395b293df12aeca13ba89414dde51003 100644 --- a/port/devip.c +++ b/port/devip.c @@ -68,7 +68,7 @@ ipinitnet(Network *np, Qinfo *stproto, Ipconv *cp) if(stproto != &udpinfo) np->listen = iplisten; np->clone = ipclonecon; - np->prot = (Netprot *)ialloc(sizeof(Netprot) * conf.ip, 0); + np->prot = (Netprot *)xalloc(sizeof(Netprot) * conf.ip); np->ninfo = 3; np->info[0].name = "remote"; np->info[0].fill = ipremotefill; @@ -83,11 +83,11 @@ ipreset(void) { int i, j; - ipifc = (Ipifc *)ialloc(sizeof(Ipifc) * conf.ip, 0); + ipifc = (Ipifc *)xalloc(sizeof(Ipifc) * conf.ip); for(i = 0; protocols[i]; i++) { - ipconv[i] = (Ipconv *)ialloc(sizeof(Ipconv) * conf.ip, 0); - ipnet[i] = (Network *)ialloc(sizeof(Network), 0); + ipconv[i] = (Ipconv *)xalloc(sizeof(Ipconv) * conf.ip); + ipnet[i] = (Network *)xalloc(sizeof(Network)); ipinitnet(ipnet[i], protocols[i], ipconv[i]); newqinfo(protocols[i]); } diff --git a/port/devmux.c b/port/devmux.c index 320b05f6dc1de679b36ffaea8decedcc9170f1bf..0f0eddb1174fe812d27af1c263dcdb9a59522cc0 100644 --- a/port/devmux.c +++ b/port/devmux.c @@ -127,7 +127,7 @@ muxinit(void) void muxreset(void) { - muxes = ialloc(conf.nmux*sizeof(Mux), 0); + muxes = xalloc(conf.nmux*sizeof(Mux)); } Chan * diff --git a/port/devscc.c b/port/devscc.c index 3cdb448e3603534a594b03d5264c110fe9fc8fb7..d1ad779d7772a1b05d38f834ebc7f8347808b892 100644 --- a/port/devscc.c +++ b/port/devscc.c @@ -665,9 +665,9 @@ sccreset(void) sp = scc[i]; if(sp->nostream) continue; - sp->iq = ialloc(sizeof(IOQ), 0); + sp->iq = xalloc(sizeof(IOQ)); initq(sp->iq); - sp->oq = ialloc(sizeof(IOQ), 0); + sp->oq = xalloc(sizeof(IOQ)); initq(sp->oq); sccenable(sp); } diff --git a/port/devsrv.c b/port/devsrv.c index 2681aa96e215e44a5d7e6f99eadee21b7392ae57..bbcc18eb0e138af77b7e40960c2d519e4400f11b 100644 --- a/port/devsrv.c +++ b/port/devsrv.c @@ -8,49 +8,56 @@ #include "devtab.h" typedef struct Srv Srv; -struct Srv{ +struct Srv +{ char name[NAMELEN]; char owner[NAMELEN]; ulong perm; Chan *chan; + Srv *link; + ulong path; }; -Lock srvlk; -Srv *srv; +static QLock srvlk; +static Srv *srv; +static int path; int srvgen(Chan *c, Dirtab *tab, int ntab, int s, Dir *dp) { Srv *sp; - if(s >= conf.nsrv) - return -1; + qlock(&srvlk); + for(sp = srv; sp && s; sp = sp->link) + s--; - sp = &srv[s]; - if(sp->chan == 0) - return 0; - devdir(c, (Qid){s, 0}, sp->name, 0, sp->owner, sp->perm, dp); + if(sp == 0) { + qunlock(&srvlk); + return -1; + } + devdir(c, (Qid){sp->path, 0}, sp->name, 0, sp->owner, sp->perm, dp); + qunlock(&srvlk); return 1; } void srvinit(void) { + path = 1; } void srvreset(void) { - srv = ialloc(conf.nsrv*sizeof(Srv), 0); } -Chan * +Chan* srvattach(char *spec) { return devattach('s', spec); } -Chan * +Chan* srvclone(Chan *c, Chan *nc) { return devclone(c, nc); @@ -68,10 +75,10 @@ srvstat(Chan *c, char *db) devstat(c, db, 0, 0, srvgen); } -Chan * +Chan* srvopen(Chan *c, int omode) { - Chan *f; + Srv *sp; if(c->qid.path == CHDIR){ if(omode != OREAD) @@ -81,60 +88,59 @@ srvopen(Chan *c, int omode) c->offset = 0; return c; } - lock(&srvlk); + qlock(&srvlk); if(waserror()){ - unlock(&srvlk); + qunlock(&srvlk); nexterror(); } - f = srv[c->qid.path].chan; - if(f == 0) + + for(sp = srv; sp; sp = sp->link) + if(sp->path == c->qid.path) + break; + + if(sp == 0 || sp->chan == 0) error(Eshutdown); + if(omode&OTRUNC) error(Eperm); - if(omode!=f->mode && f->mode!=ORDWR) + if(omode!=sp->chan->mode && sp->chan->mode!=ORDWR) error(Eperm); + close(c); - incref(f); - unlock(&srvlk); + incref(sp->chan); + qunlock(&srvlk); poperror(); - return f; + return sp->chan; } void srvcreate(Chan *c, char *name, int omode, ulong perm) { - int j, i; Srv *sp; if(omode != OWRITE) error(Eperm); - lock(&srvlk); + sp = malloc(sizeof(Srv)); + if(sp == 0) + error(Enomem); + + qlock(&srvlk); if(waserror()){ - unlock(&srvlk); + qunlock(&srvlk); nexterror(); } - j = -1; - for(i=0; ichan = c; - incref(c); - unlock(&srvlk); + sp->path = path++; + sp->link = srv; + c->qid.path = sp->path; + srv = sp; + qunlock(&srvlk); poperror(); + strncpy(sp->name, name, NAMELEN); strncpy(sp->owner, u->p->user, NAMELEN); sp->perm = perm&0777; - c->qid.path = j; c->flag |= COPEN; c->mode = OWRITE; } @@ -143,24 +149,36 @@ void srvremove(Chan *c) { Chan *f; + Srv *sp, **l; if(c->qid.path == CHDIR) error(Eperm); - lock(&srvlk); + qlock(&srvlk); if(waserror()){ - unlock(&srvlk); + qunlock(&srvlk); nexterror(); } - f = srv[c->qid.path].chan; - if(f == 0) - error(Eshutdown); - if(strcmp(srv[c->qid.path].name, "boot") == 0) + l = &srv; + for(sp = *l; sp; sp = sp->link) { + if(sp->path == c->qid.path) + break; + + l = &srv->link; + } + if(sp == 0) + error(Enonexist); + + if(strcmp(sp->name, "boot") == 0) error(Eperm); - srv[c->qid.path].chan = 0; - unlock(&srvlk); + + *l = sp->link; + qunlock(&srvlk); poperror(); - close(f); + + if(sp->chan) + close(sp->chan); + free(sp); } void @@ -186,10 +204,11 @@ srvread(Chan *c, void *va, long n, ulong offset) long srvwrite(Chan *c, void *va, long n, ulong offset) { + Srv *sp; Fgrp *f; + Chan *c1; int i, fd; char buf[32]; - Chan *c1; if(n >= sizeof buf) error(Egreg); @@ -209,18 +228,24 @@ srvwrite(Chan *c, void *va, long n, ulong offset) unlock(f); poperror(); - lock(&srvlk); - if (waserror()) { - unlock(&srvlk); + qlock(&srvlk); + if(waserror()) { + qunlock(&srvlk); close(c1); nexterror(); } - i = c->qid.path; - if(srv[i].chan != c) /* already been written to */ - error(Egreg); + for(sp = srv; sp; sp = sp->link) + if(sp->path == c->qid.path) + break; + + if(sp == 0) + error(Enonexist); + + if(sp->chan) + panic("srvwrite"); - srv[i].chan = c1; - unlock(&srvlk); + sp->chan = c1; + qunlock(&srvlk); poperror(); return n; } diff --git a/port/error.h b/port/error.h index 7e774fcf400d6267eebc0e1da1b5a8d571d74654..e6f4909f6e90e4b265956d6bc327d4b74289977b 100644 --- a/port/error.h +++ b/port/error.h @@ -23,7 +23,6 @@ extern char Ebadbitmap[]; /* unallocated bitmap */ extern char Enobitmap[]; /* out of bitmap descriptors */ extern char Enobitstore[]; /* out of bitmap storage */ extern char Ebadfont[]; /* unallocated font */ -extern char Enofont[]; /* no free font descriptors */ extern char Enetaddr[]; /* bad network address */ extern char Emsgsize[]; /* message is too big for protocol */ extern char Enetbusy[]; /* network device is busy or allocated */ @@ -51,4 +50,5 @@ extern char Econrefused[]; /* connection refused */ extern char Enetunreach[]; /* network unreachable */ extern char Eintr[]; /* interrupted */ extern char Eneedservice[]; /* service required for tcp/udp/il calls */ +extern char Enomem[]; /* kernel allocate failed */ extern char Egreg[]; /* it's a thermal problem */ diff --git a/port/page.c b/port/page.c index f2a240ee88926620f2afc947bee8fe6c1f82114b..489d3dfabeadb13eb07712ebfaaa851f058c08df 100644 --- a/port/page.c +++ b/port/page.c @@ -21,7 +21,7 @@ pageinit(void) palloc.head = xalloc(np*sizeof(Page)); if(palloc.head == 0) panic("pageinit"); -print("page: %lux %d %lux %d\n", palloc.p0, palloc.np0, palloc.p1, palloc.np1); + p = palloc.head; while(palloc.np0 > 0) { p->prev = p-1; diff --git a/port/portfns.h b/port/portfns.h index 668e93dfec09222b25e4e08bdf3dde611809914f..513c2abab574844cb7d24f9f4617374ef2c22939 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -1,253 +1,251 @@ -void alarmkproc(void*); -Block* allocb(ulong); -int anyready(void); -Image* attachimage(int, Chan*, ulong, ulong); -int blen(Block *); -int bround(Block *, int); -void buzz(int, int); -void cachepage(Page*, Image*); -int cangetc(void*); -int canlock(Lock*); -int canpage(Proc*); -int canputc(void*); -int canqlock(QLock*); -void chandevinit(void); -void chandevreset(void); -void chanfree(Chan*); -void checkalarms(void); -void clock(Ureg*); -Chan* clone(Chan*, Chan*); -void close(Chan*); -void closeegrp(Egrp*); -void closefgrp(Fgrp*); -void closemount(Mount*); -void closepgrp(Pgrp*); -long clrfpintr(void); -void confinit(void); -void confinit1(int); -int consactive(void); -void consdebug(void); -Block *copyb(Block*, int); -Env* copyenv(Env*, int); -void copypage(Page*, Page*); -int decref(Ref*); -int decrypt(void*, void*, int); -void delay(int); -Chan* devattach(int, char*); -Chan* devclone(Chan*, Chan*); -void devdir(Chan*, Qid, char*, long, char*, long, Dir*); -long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*); -Devgen devgen; -int devno(int, int); -Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); -void devstat(Chan*, char*, Dirtab*, int, Devgen*); -int devwalk(Chan*, char*, Dirtab*, int, Devgen*); -void dumpqueues(void); -void dumpregs(Ureg*); -void dumpstack(void); -Fgrp* dupfgrp(Fgrp*); -void duppage(Page*); -Segment* dupseg(Segment*, int); -void dupswap(Page*); -int encrypt(void*, void*, int); -void envcpy(Egrp*, Egrp*); -void envpgclose(Env*); -void envpgcopy(Env*, Env*); -int eqchan(Chan*, Chan*, long); -int eqqid(Qid, Qid); -void error(char*); -long execregs(ulong, ulong, ulong); -void exhausted(char*); -void exit(void); -Block* expandb(Block*, int); -int fault(ulong, int); -void fdclose(int, int); -Chan* fdtochan(int, int, int); -int fixfault(Segment*, ulong, int, int); -void flowctl(Queue*, Block*); -void flushmmu(void); -void freeb(Block*); -int freebroken(void); -void freechan(Chan*); -void freepte(Segment*, Pte*); -void freesegs(int); -Block* getb(Blist*); -int getc(IOQ*); -void getcolor(ulong, ulong*, ulong*, ulong*); -int getfields(char*, char**, int, char); -Block* getq(Queue*); -int gets(IOQ*, void*, int); -void gotolabel(Label*); -Block* grabq(Queue*); -int hwcursmove(int, int); -int hwcursset(uchar*, uchar*, int, int); -void* ialloc(ulong, int); -void* iallocspan(ulong, int, ulong); -long ibrk(ulong, int); -int incref(Ref*); -void initq(IOQ*); -void initseg(void); -void invalidateu(void); -void isdir(Chan*); -int ispages(void*); -void kbdclock(void); -int kbdcr2nl(IOQ*, int); -int kbdputc(IOQ*, int); -void kbdrepeat(int); -void kickpager(void); -int kprint(char*, ...); -void kproc(char*, void(*)(void*), void*); -void kproftimer(ulong); -void ksetenv(char*, char*); -void ksetterm(char*); -long latin1(uchar*); -void lights(int); -void lock(Lock*); -void lockinit(void); -void lockpage(Page*); -Page* lookpage(Image*, ulong); -void machinit(void); -void mapstack(Proc*); -void mfreeseg(Segment*, ulong, int); -void mmurelease(Proc*); -void mntdump(void); -int mount(Chan*, Chan*, int); -void mouseclock(void); -int mouseputc(IOQ*, int); -Chan* namec(char*, int, int, ulong); -void nameok(char*); -void netdisown(Network*, int); -int netgen(Chan*, void*, int, int, Dir*); -Chan* netopen(Chan*, int, Network*); -int netown(Network*, int, char*, int); -long netread(Chan*, void*, long, ulong, Network*); -void netstat(Chan*, char*, Network*); -int netwalk(Chan*, char*, Network*); -void netwstat(Chan*, char*, Network*); -Chan* newchan(void); -Egrp* newegrp(void); -Fgrp* newfgrp(void); -Mount* newmount(Mhead*, Chan*); -Page* newpage(int, Segment **, ulong); -Pgrp* newpgrp(void); -Proc* newproc(void); -void newqinfo(Qinfo*); +void alarmkproc(void*); +Block* allocb(ulong); +int anyready(void); +Image* attachimage(int, Chan*, ulong, ulong); +int blen(Block *); +int bround(Block *, int); +void buzz(int, int); +void cachepage(Page*, Image*); +int cangetc(void*); +int canlock(Lock*); +int canpage(Proc*); +int canputc(void*); +int canqlock(QLock*); +void chandevinit(void); +void chandevreset(void); +void chanfree(Chan*); +void checkalarms(void); +void clock(Ureg*); +Chan* clone(Chan*, Chan*); +void close(Chan*); +void closeegrp(Egrp*); +void closefgrp(Fgrp*); +void closemount(Mount*); +void closepgrp(Pgrp*); +long clrfpintr(void); +void confinit(void); +void confinit1(int); +int consactive(void); +void consdebug(void); +Block* copyb(Block*, int); +Env* copyenv(Env*, int); +void copypage(Page*, Page*); +int decref(Ref*); +int decrypt(void*, void*, int); +void delay(int); +Chan* devattach(int, char*); +Chan* devclone(Chan*, Chan*); +void devdir(Chan*, Qid, char*, long, char*, long, Dir*); +long devdirread(Chan*, char*, long, Dirtab*, int, Devgen*); +Devgen devgen; +int devno(int, int); +Chan* devopen(Chan*, int, Dirtab*, int, Devgen*); +void devstat(Chan*, char*, Dirtab*, int, Devgen*); +int devwalk(Chan*, char*, Dirtab*, int, Devgen*); +void dumpqueues(void); +void dumpregs(Ureg*); +void dumpstack(void); +Fgrp* dupfgrp(Fgrp*); +void duppage(Page*); +void dupswap(Page*); +int encrypt(void*, void*, int); +void envcpy(Egrp*, Egrp*); +void envpgclose(Env*); +void envpgcopy(Env*, Env*); +int eqchan(Chan*, Chan*, long); +int eqqid(Qid, Qid); +void error(char*); +long execregs(ulong, ulong, ulong); +void exhausted(char*); +void exit(void); +Block* expandb(Block*, int); +int fault(ulong, int); +void fdclose(int, int); +Chan* fdtochan(int, int, int); +int fixfault(Segment*, ulong, int, int); +void flowctl(Queue*, Block*); +void flushmmu(void); +void free(void*); +void freeb(Block*); +int freebroken(void); +void freechan(Chan*); +void freepte(Segment*, Pte*); +void freesegs(int); +Block* getb(Blist*); +int getc(IOQ*); +void getcolor(ulong, ulong*, ulong*, ulong*); +int getfields(char*, char**, int, char); +Block* getq(Queue*); +int gets(IOQ*, void*, int); +void gotolabel(Label*); +Block* grabq(Queue*); +int hwcursmove(int, int); +int hwcursset(uchar*, uchar*, int, int); +long ibrk(ulong, int); +int incref(Ref*); +void initq(IOQ*); +void initseg(void); +void invalidateu(void); +void isdir(Chan*); +int ispages(void*); +void kbdclock(void); +int kbdcr2nl(IOQ*, int); +int kbdputc(IOQ*, int); +void kbdrepeat(int); +void kickpager(void); +int kprint(char*, ...); +void kproc(char*, void(*)(void*), void*); +void kproftimer(ulong); +void ksetenv(char*, char*); +void ksetterm(char*); +long latin1(uchar*); +void lights(int); +void lock(Lock*); +void lockinit(void); +void lockpage(Page*); +Page* lookpage(Image*, ulong); +void machinit(void); +void* malloc(ulong); +void mapstack(Proc*); +void mfreeseg(Segment*, ulong, int); +void mmurelease(Proc*); +void mntdump(void); +int mount(Chan*, Chan*, int); +void mountfree(Mount*); +void mouseclock(void); +int mouseputc(IOQ*, int); +Chan* namec(char*, int, int, ulong); +void nameok(char*); +void netdisown(Network*, int); +int netgen(Chan*, void*, int, int, Dir*); +Chan* netopen(Chan*, int, Network*); +int netown(Network*, int, char*, int); +long netread(Chan*, void*, long, ulong, Network*); +void netstat(Chan*, char*, Network*); +int netwalk(Chan*, char*, Network*); +void netwstat(Chan*, char*, Network*); +Chan* newchan(void); +Egrp* newegrp(void); +Fgrp* newfgrp(void); +Mount* newmount(Mhead*, Chan*); +Page* newpage(int, Segment **, ulong); +Pgrp* newpgrp(void); +Proc* newproc(void); +void newqinfo(Qinfo*); Segment* newseg(int, ulong, ulong); -char* nextelem(char*, char*); -void nexterror(void); -int nodelims(Stream*); -int notify(Ureg*); -int nrand(int); -void nullput(Queue*, Block*); -int okaddr(ulong, ulong, int); -int openmode(ulong); -Block* padb(Block*, int); -void pageinit(void); -void panic(char*, ...); -void pexit(char*, int); -void pgrpcpy(Pgrp*, Pgrp*); -void pgrpnote(ulong, char*, long, int); -Pgrp* pgrptab(int); -void pio(Segment *, ulong, ulong, Page **); -#define poperror() u->nerrlab-- -int postnote(Proc*, int, char*, int); -int pprint(char*, ...); -void printinit(void); -ulong procalarm(ulong); -void procctl(Proc*); -void procdump(void); -void procinit0(void); -Proc* proctab(int); -Pte* ptealloc(void); -Pte* ptecpy(Pte*); -Block* pullup(Block *, int); -Queue* pushq(Stream*, Qinfo*); -int putb(Blist*, Block*); -void putbq(Blist*, Block*); -int putc(IOQ*, int); -void putimage(Image*); -void putmmu(ulong, ulong, Page*); -void putpage(Page*); -int putq(Queue*, Block*); -void puts(IOQ*, void*, int); -void putseg(Segment*); -void putstr(char*); -void putstr(char*); -void putstrn(char*, long); -void putswap(Page*); -ulong pwait(Waitmsg*); -Qinfo* qinfofind(char*); -void qlock(QLock*); -void qunlock(QLock*); -int readnum(ulong, char*, ulong, ulong, int); -void ready(Proc*); -void relocateseg(Segment*, ulong); -void resched(char*); -void resrcwait(char*); -int return0(void*); -Proc* runproc(void); -void savefpregs(FPsave*); -void sccclock(void); -void sccintr(void); -void sccsetup(void*, ulong); -void sccspecial(int, IOQ*, IOQ*, int); -void sched(void); -void schedinit(void); -int screenbits(void); -long seconds(void); +char* nextelem(char*, char*); +void nexterror(void); +int nodelims(Stream*); +int notify(Ureg*); +int nrand(int); +void nullput(Queue*, Block*); +int okaddr(ulong, ulong, int); +int openmode(ulong); +Block* padb(Block*, int); +void pageinit(void); +void panic(char*, ...); +void pexit(char*, int); +void pgrpcpy(Pgrp*, Pgrp*); +void pgrpnote(ulong, char*, long, int); +Pgrp* pgrptab(int); +void pio(Segment *, ulong, ulong, Page **); +#define poperror() u->nerrlab-- +int postnote(Proc*, int, char*, int); +int pprint(char*, ...); +void printinit(void); +ulong procalarm(ulong); +void procctl(Proc*); +void procdump(void); +void procinit0(void); +Proc* proctab(int); +Pte* ptealloc(void); +Pte* ptecpy(Pte*); +Block* pullup(Block *, int); +Queue* pushq(Stream*, Qinfo*); +int putb(Blist*, Block*); +void putbq(Blist*, Block*); +int putc(IOQ*, int); +void putimage(Image*); +void putmmu(ulong, ulong, Page*); +void putpage(Page*); +int putq(Queue*, Block*); +void puts(IOQ*, void*, int); +void putseg(Segment*); +void putstr(char*); +void putstr(char*); +void putstrn(char*, long); +void putswap(Page*); +ulong pwait(Waitmsg*); +Qinfo* qinfofind(char*); +void qlock(QLock*); +void qunlock(QLock*); +int readnum(ulong, char*, ulong, ulong, int); +void ready(Proc*); +void relocateseg(Segment*, ulong); +void resched(char*); +void resrcwait(char*); +int return0(void*); +void rlock(RWlock*); +void runlock(RWlock*); +Proc* runproc(void); +void savefpregs(FPsave*); +void sccclock(void); +void sccintr(void); +void sccsetup(void*, ulong); +void sccspecial(int, IOQ*, IOQ*, int); +void sched(void); +void schedinit(void); +int screenbits(void); +long seconds(void); +ulong segattach(Proc*, ulong, char *, ulong, ulong); +void segpage(Segment*, Page*); +int setcolor(ulong, ulong, ulong, ulong); +int setlabel(Label*); +void setregisters(Ureg*, char*, char*, int); +void setswapchan(Chan*); +void simpleputpage(Page*); +char* skipslash(char*); +void sleep(Rendez*, int(*)(void*), void*); +void* smalloc(ulong); +int splhi(void); +int spllo(void); +void splx(int); +int streamclose(Chan*); +int streamclose1(Stream*); +int streamenter(Stream*); +int streamexit(Stream*, int); +Devgen streamgen; +void streaminit(void); +void streaminit0(void); +Stream* streamnew(ushort, ushort, ushort, Qinfo*, int); +void streamopen(Chan*, Qinfo*); +int streamparse(char*, Block*); +long streamread(Chan*, void*, long); +void streamstat(Chan*, char*, char*); +long streamwrite(Chan*, void*, long, int); +long stringread(void*, long, char*, ulong); +void swapinit(void); +long syscall(Ureg*); +void tsleep(Rendez*, int (*)(void*), void*, int); +void uncachepage(Page*); +long unicode(uchar*); +long unionread(Chan*, void*, long); +void unlock(Lock*); +void unlockpage(Page*); +void unmount(Chan*, Chan*); +void urpfillstats(Chan*, char*, int); +void userinit(void); +ulong userpc(void); +void validaddr(ulong, ulong, int); +void* vmemchr(void*, int, int); +void wakeup(Rendez*); +void wlock(RWlock*); +void wunlock(RWlock*); +void* xalloc(ulong); +void xfree(void*); +void xhole(ulong, ulong); +void xinit(void); +void* xspanalloc(ulong, int, ulong); +void xsummary(void); +Segment* dupseg(Segment*, int); Segment* seg(Proc*, ulong, int); -ulong segattach(Proc*, ulong, char *, ulong, ulong); -void segpage(Segment*, Page*); -int setcolor(ulong, ulong, ulong, ulong); -int setlabel(Label*); -void setregisters(Ureg*, char*, char*, int); -void setswapchan(Chan*); -void simpleputpage(Page*); -char* skipslash(char*); -void sleep(Rendez*, int(*)(void*), void*); -int splhi(void); -int spllo(void); -void splx(int); -int streamclose(Chan*); -int streamclose1(Stream*); -int streamenter(Stream*); -int streamexit(Stream*, int); -Devgen streamgen; -void streaminit(void); -void streaminit0(void); -Stream* streamnew(ushort, ushort, ushort, Qinfo*, int); -void streamopen(Chan*, Qinfo*); -int streamparse(char*, Block*); -long streamread(Chan*, void*, long); -void streamstat(Chan*, char*, char*); -long streamwrite(Chan*, void*, long, int); -long stringread(void*, long, char*, ulong); -void swapinit(void); -long syscall(Ureg*); -void tsleep(Rendez*, int (*)(void*), void*, int); -void uncachepage(Page*); -long unionread(Chan*, void*, long); -void unlock(Lock*); -void unlockpage(Page*); -long unicode(uchar*); -void userinit(void); -ulong userpc(void); -void validaddr(ulong, ulong, int); -void* vmemchr(void*, int, int); -void wakeup(Rendez*); -void rlock(RWlock*); -void runlock(RWlock*); -void wlock(RWlock*); -void wunlock(RWlock*); -void mountfree(Mount*); -void unmount(Chan*, Chan*); -void urpfillstats(Chan*, char*, int); -void xinit(void); -void *xalloc(ulong); -void *xspanalloc(ulong, int, ulong); -void xfree(void*); -void xhole(ulong, ulong); -void xsummary(void); -void *malloc(ulong); -void *smalloc(ulong); -void free(void*); diff --git a/port/proc.c b/port/proc.c index f8b2c7ce140ecb5f0e3aacc58f1d47772b1addba..265dc1c4911e686b9b5443cb0c26a4e1f769d290 100644 --- a/port/proc.c +++ b/port/proc.c @@ -157,9 +157,9 @@ runproc(void) loop: spllo(); while(runhiq.head==0 && runloq.head==0) - for(i=0; i<10; i++) /* keep out of shared memory for a while */ - ; + ; splhi(); + lock(&runhiq); if(runhiq.head) rq = &runhiq; diff --git a/port/stasync.c b/port/stasync.c index 94b907c6702cd00f811edcb29f7266d2d9a4e9d5..70e0dd01938a214a760ad6bf30ceb0e1fc794b02 100644 --- a/port/stasync.c +++ b/port/stasync.c @@ -15,7 +15,14 @@ enum { }; /* input states */ -enum { Hunt=0, Framing, Framed, Data, Escape }; +enum +{ + Hunt, + Framing, + Framed, + Data, + Escape +}; typedef struct Async { QLock; @@ -24,7 +31,6 @@ typedef struct Async { Queue *wq; /* output state */ - QLock xmit; /* transmit lock */ int chan; /* current urp channel */ Block *bp; /* current output buffer */ @@ -32,14 +38,12 @@ typedef struct Async { ushort crc; /* input state */ - int state; /* input state */ uchar buf[MAXFRAME]; /* current input buffer */ int icount; ushort icrc; /* statistics */ - ulong chan0; ulong toolong; ulong tooshort; @@ -93,7 +97,7 @@ static ushort crc_table[256] = { static void asyncreset(void) { - async = (Async *)ialloc(conf.nasync*sizeof(Async), 0); + async = (Async *)xalloc(conf.nasync*sizeof(Async)); } /* diff --git a/port/stip.c b/port/stip.c index f91676e7f75cd101470bc51966ae45ad980b1aef..ee4425df7790048bb54aad8a85e84ee17433a2bb 100644 --- a/port/stip.c +++ b/port/stip.c @@ -55,7 +55,7 @@ initfrag(int size) { Fragq *fq, *eq; - fragfree = (Fragq*)ialloc(sizeof(Fragq) * size, 0); + fragfree = (Fragq*)xalloc(sizeof(Fragq) * size); eq = &fragfree[size]; for(fq = fragfree; fq < eq; fq++) diff --git a/port/stlapd.c b/port/stlapd.c index 6a6c4a0e52a61122812129ece7e89720676aa14f..fc9f8b0b85e55c1ce1462faeb8b03789466454ef 100644 --- a/port/stlapd.c +++ b/port/stlapd.c @@ -10,35 +10,36 @@ typedef struct Lapd Lapd; -#define NOW TK2MS(MACHP(0)->ticks) -#define T200 (NOW+2500) - - /* C/R bits */ - -#define UCmd 0 /* command, user to network */ -#define UResp 2 /* response, user to network */ -#define NCmd 2 /* command, network to user */ -#define NResp 0 /* response, network to user */ - +#define NOW TK2MS(MACHP(0)->ticks) +#define T200 (NOW+2500) #define SAPI(s, cr) (((s)<<2)|cr) #define TEI(t) (((t)<<1)|1) /* * Commands and responses */ +enum +{ + RR = 0x01, /* Receiver Ready */ + RNR = 0x05, /* Receiver Not Ready */ + REJ = 0x09, /* Reject */ + SABME = 0x6f, /* Set Asynchronous Balanced Mode Extended */ + DM = 0x0f, /* Disconnect Mode */ + UI = 0x03, /* Unnumbered Information */ + DISC = 0x43, /* Disconnect */ + UA = 0x63, /* Unnumbered Acknowledgement */ + FRMR = 0x87, /* Frame Reject */ + XID = 0xaf, /* Exchange Identification */ -#define RR 0x01 /* Receiver Ready */ -#define RNR 0x05 /* Receiver Not Ready */ -#define REJ 0x09 /* Reject */ -#define SABME 0x6f /* Set Asynchronous Balanced Mode Extended */ -#define DM 0x0f /* Disconnect Mode */ -#define UI 0x03 /* Unnumbered Information */ -#define DISC 0x43 /* Disconnect */ -#define UA 0x63 /* Unnumbered Acknowledgement */ -#define FRMR 0x87 /* Frame Reject */ -#define XID 0xaf /* Exchange Identification */ - -enum States { + /* C/R bits */ + UCmd = 0, /* command, user to network */ + UResp = 2, /* response, user to network */ + NCmd = 2, /* command, network to user */ + NResp = 0 /* response, network to user */ +}; + +enum States +{ Unused = 0, NoTEI, WaitTEI, @@ -48,12 +49,13 @@ enum States { WaitRel, }; -enum Flags { - Ownbusy = 0x01, - Peerbusy = 0x02, - Rejecting = 0x04, - Timeout = 0x08, - Hungup = 0x80 +enum Flags +{ + Ownbusy = 0x01, + Peerbusy = 0x02, + Rejecting = 0x04, + Timeout = 0x08, + Hungup = 0x80 }; #define SMASK 127 @@ -69,7 +71,8 @@ enum Flags { #define RSTATE(lp) ((lp->flags&Ownbusy) ? RNR : \ (lp->flags&Rejecting) ? REJ : RR) -struct Lapd { +struct Lapd +{ QLock; /* access, state change */ Rendez; /* waiting for state change */ int state; @@ -158,7 +161,7 @@ lapderror(Lapd *lp, int code) static void lapdreset(void) { - lapd = ialloc(conf.nlapd*sizeof(Lapd), 0); + lapd = xalloc(conf.nlapd*sizeof(Lapd)); } static void diff --git a/port/sturp.c b/port/sturp.c index c90c8de110bd8df6a2bee3a15986954136458a14..4913d5a2913b3ecedb11f5112536a5605a437d13 100644 --- a/port/sturp.c +++ b/port/sturp.c @@ -135,7 +135,7 @@ Qinfo urpinfo = static void urpreset(void) { - urp = (Urp *)ialloc(conf.nurp*sizeof(Urp), 0); + urp = (Urp *)xalloc(conf.nurp*sizeof(Urp)); } static void diff --git a/port/sysproc.c b/port/sysproc.c index 4481d593d1b36f950184218fe571391c737f9dac..3aa8ff6e0a343d692b26ccb4df80ab508b92a547 100644 --- a/port/sysproc.c +++ b/port/sysproc.c @@ -8,7 +8,6 @@ #include int shargs(char*, int, char**); -long rfork(ulong); long sysr1(ulong *arg) @@ -17,52 +16,24 @@ sysr1(ulong *arg) return 0; } -enum /* Argument to forkpgrp call */ -{ - FPall = 0, /* Concession to back portablility */ - FPnote = 1, - FPnamespc = 2, - FPenv = 4, - FPclear = 8, -}; - -long -sys__fork__(ulong *arg) -{ - USED(arg); - return rfork(RFFDG|RFPROC); -} - -long -sys__rfork__(ulong *arg) -{ - return rfork(arg[0]|RFPROC); -} - -/* This call will obsolete fork */ long sysrfork(ulong *arg) { - return rfork(arg[0]); -} - -long -rfork(ulong flag) -{ - Proc *p, *parent; - Segment *s; - ulong usp, upa, pid; - int n, on, i; Chan *c; KMap *k; Pgrp *opg; Egrp *oeg; Fgrp *ofg; + Segment *s; + int n, on, i; + Proc *p, *parent; + ulong usp, upa, pid, flag; /* * used to compute last valid system stack address for copy */ int lastvar; + flag = arg[0]; p = u->p; if((flag&RFPROC) == 0) { if(flag & (RFNAMEG|RFCNAMEG)) { @@ -521,36 +492,6 @@ syswait(ulong *arg) return pwait((Waitmsg*)arg[0]); } -long -sys__wait__(ulong *arg) /* binary compatibility: BUG */ -{ - int i; - - struct oldWaitmsg - { - int pid; /* of loved one */ - int status; /* unused; a vestige */ - long time[3]; /* of loved one & descendants */ - char msg[ERRLEN]; - } *wp; - Waitmsg w; - - if(arg[0]){ - validaddr(arg[0], sizeof(struct oldWaitmsg), 1); - evenaddr(arg[0]); - i = pwait(&w); - wp = (struct oldWaitmsg*)arg[0]; - wp->pid = atoi(w.pid); - wp->status = 0; - wp->time[TUser] = atoi(w.time+TUser*NUMSIZE); - wp->time[TSys] = atoi(w.time+TSys*NUMSIZE); - wp->time[TReal] = atoi(w.time+TReal*NUMSIZE); - memmove(wp->msg, w.msg, ERRLEN); - return i; - } - return pwait(0); -} - long sysdeath(ulong *arg) { @@ -571,48 +512,6 @@ syserrstr(ulong *arg) return 0; } -long -sys__forkpgrp__(ulong *arg) -{ - int mask; - Pgrp *pg; - Egrp *eg; - - pg = newpgrp(); - eg = newegrp(); - if(waserror()){ - closepgrp(pg); - closeegrp(eg); - nexterror(); - } - - mask = arg[0]; - if(mask == FPall) - mask = FPnote|FPenv|FPnamespc; - - if(mask & FPnamespc) - pgrpcpy(pg, u->p->pgrp); - else - *pg->crypt = *u->p->pgrp->crypt; - - if(mask & FPenv) - envcpy(eg, u->p->egrp); - - if((mask & FPnote) == 0) { - u->nnote = 0; - u->notified = 0; - memset(u->note, 0, sizeof(u->note)); - } - u->p->noteid = incref(¬eidalloc); - - poperror(); - closepgrp(u->p->pgrp); - closeegrp(u->p->egrp); - u->p->pgrp = pg; - u->p->egrp = eg; - return pg->pgrpid; -} - long sysnotify(ulong *arg) { diff --git a/port/systab.h b/port/systab.h index 98c2a0674469f33b44edc185ae962261636b4dcb..5de5f87af2f72b19fb5e650303eb951ce6cc72be 100644 --- a/port/systab.h +++ b/port/systab.h @@ -12,8 +12,8 @@ Syscall sysdup; Syscall sysalarm; Syscall sysexec; Syscall sysexits; -Syscall sys__fork__; -Syscall sys__forkpgrp__; +Syscall sysdeath; +Syscall sysdeath; Syscall sysfstat; Syscall syssegbrk; Syscall sysmount; @@ -26,7 +26,7 @@ Syscall sysrfork; Syscall syswrite; Syscall syspipe; Syscall syscreate; -Syscall sys__rfork__; +Syscall sysdeath; Syscall sysbrk_; Syscall sysremove; Syscall syswstat; @@ -51,8 +51,8 @@ Syscall *systab[]={ [ALARM] sysalarm, [EXEC] sysexec, [EXITS] sysexits, - [__FORK__] sys__fork__, - [__FORKPGRP__] sys__forkpgrp__, + [__FORK__] sysdeath, + [__FORKPGRP__] sysdeath, [FSTAT] sysfstat, [SEGBRK] syssegbrk, [MOUNT] sysmount, @@ -65,7 +65,7 @@ Syscall *systab[]={ [WRITE] syswrite, [PIPE] syspipe, [CREATE] syscreate, - [__RFORK__] sys__rfork__, + [__RFORK__] sysdeath, [BRK_] sysbrk_, [REMOVE] sysremove, [WSTAT] syswstat, diff --git a/power/conf.h b/power/conf.h index 2cfc3be7e63cda200a7896818312adffde9a62db..cd4b4293b3eae720fcedd644d9a0299045ae22a7 100644 --- a/power/conf.h +++ b/power/conf.h @@ -1,32 +1,19 @@ Conftab conftab[] = { {"nmach", &conf.nmach }, {"nproc", &conf.nproc }, - {"npgrp", &conf.npgrp }, {"npage0", &conf.npage0 }, {"npage1", &conf.npage1 }, {"npage", &conf.npage }, - {"nseg", &conf.nseg }, {"nimage", &conf.nimage }, - {"npagetab", &conf.npagetab }, {"nswap", &conf.nswap }, - {"nalarm", &conf.nalarm }, - {"nchan", &conf.nchan }, {"nenv", &conf.nenv }, {"nenvchar", &conf.nenvchar }, {"npgenv", &conf.npgenv }, - {"nmtab", &conf.nmtab }, - {"nmount", &conf.nmount }, - {"nmntdev", &conf.nmntdev }, - {"nmntbuf", &conf.nmntbuf }, - {"nmnthdr", &conf.nmnthdr }, {"nstream", &conf.nstream }, {"nqueue", &conf.nqueue }, - {"nblock", &conf.nblock }, {"nsrv", &conf.nsrv }, {"nurp", &conf.nurp }, {"nasync", &conf.nasync }, - {"npipe", &conf.npipe }, - {"maxialloc", &conf.maxialloc }, {"base0", &conf.base0 }, {"base1", &conf.base1 }, {"copymode", &conf.copymode }, diff --git a/power/dat.h b/power/dat.h index c08ce0e128527badb5d2e355eda7f1c24a8b28e6..a588112f71837d43d73ed4519c89cd873764f0dd 100644 --- a/power/dat.h +++ b/power/dat.h @@ -23,7 +23,7 @@ typedef struct User User; struct Lock { - ulong *sbsem; /* addr of sync bus semaphore */ + int val; ulong pc; }; @@ -37,32 +37,20 @@ struct Conf { ulong nmach; /* processors */ ulong nproc; /* processes */ - ulong npgrp; /* process groups */ ulong npage0; /* total physical pages of memory */ ulong npage1; /* total physical pages of memory */ ulong npage; /* total physical pages of memory */ - ulong nseg; /* number of segments */ + ulong upages; /* user page pool */ ulong nimage; /* number of page cache image headers */ - ulong npagetab; /* number of pte tables */ ulong nswap; /* number of swap pages */ - ulong nalarm; /* alarms */ - ulong nchan; /* channels */ ulong nenv; /* distinct environment values */ ulong nenvchar; /* environment text storage */ ulong npgenv; /* environment files per process group */ - ulong nmtab; /* mounted-upon channels per process group */ - ulong nmount; /* mounts */ - ulong nmntdev; /* mounted devices (devmnt.c) */ - ulong nmntbuf; /* buffers for devmnt.c messages */ - ulong nmnthdr; /* headers for devmnt.c messages */ ulong nstream; /* streams */ ulong nqueue; /* stream queues */ - ulong nblock; /* stream blocks */ ulong nsrv; /* public servers (devsrv.c) */ ulong nurp; /* max urp conversations */ ulong nasync; /* number of async protocol modules */ - ulong npipe; /* number of pipes */ - ulong maxialloc; /* maximum bytes used by ialloc */ ulong base0; /* base of bank 0 */ ulong base1; /* base of bank 1 */ ulong copymode; /* 0 is copy on write, 1 is copy on reference */ diff --git a/power/devcyc.c b/power/devcyc.c index ce69a043044bdeb0192f8ce5c8c4b3c1ebf09e46..628fa1968682e2bc6a76f7c0ea6f6570fd0f9790 100644 --- a/power/devcyc.c +++ b/power/devcyc.c @@ -5,7 +5,6 @@ #include "fns.h" #include "../port/error.h" #include "devtab.h" -#include "fcall.h" #include "io.h" #include "../../fs/cyc/comm.h" diff --git a/power/devduart.c b/power/devduart.c index 85db5b54c356345388b51a5e7ce2dcacddbfd4e4..775fb67c489724e7f48c10b398a1d9ab26aa9cdc 100644 --- a/power/devduart.c +++ b/power/devduart.c @@ -695,7 +695,7 @@ duartreset(void) * allocate the directory and fill it in */ nduartport = 2*conf.nmach; - duartdir = ialloc(nduartport*2*sizeof(Dirtab), 0); + duartdir = xalloc(nduartport*2*sizeof(Dirtab)); for(i = 0; i < nduartport; i++){ sprint(duartdir[2*i].name, "eia%d", i+1); sprint(duartdir[2*i+1].name, "eia%dctl", i+1); @@ -714,11 +714,11 @@ duartreset(void) if(p->nostream) continue; - p->iq = ialloc(sizeof(IOQ), 0); + p->iq = xalloc(sizeof(IOQ)); initq(p->iq); p->iq->ptr = p; - p->oq = ialloc(sizeof(IOQ), 0); + p->oq = xalloc(sizeof(IOQ)); initq(p->oq); p->oq->ptr = p; p->oq->puts = duartputs; diff --git a/power/fns.h b/power/fns.h index c74a3c37a57214355d5115e76829b90a66ad1508..09b34c53dea1e5812670e5a964a2ce750ab8369f 100644 --- a/power/fns.h +++ b/power/fns.h @@ -71,3 +71,5 @@ void vmereset(void); void wbflush(void); #define waserror() setlabel(&u->errlab[u->nerrlab++]) #define kmapperm(x) kmap(x) +#define KADDR(a) ((void*)((ulong)(a)|KZERO)) +#define PADDR(a) ((ulong)(a)&~KZERO) diff --git a/power/lock.c b/power/lock.c index 51856109eba95096b45d383da0ca4a629159e788..4f145ab9b49cd7a55a4ae6b027ac01651eddf7b4 100644 --- a/power/lock.c +++ b/power/lock.c @@ -13,51 +13,35 @@ * Writing a semaphore sets the value, so writing 0 resets (clears) the semaphore. */ -#define SEMPERPG 64 /* hardware semaphores per page */ -#define NSEMPG 1024 -#define ULOCKPG 512 +enum +{ + SEMPERPG = 64, /* hardware semaphores per page */ + NSEMPG = 1024, + ULOCKPG = 512, +}; struct { Lock lock; /* lock to allocate */ - ulong *nextsem; /* next one to allocate */ - int nsem; /* at SEMPERPG, jump to next page */ uchar bmap[NSEMPG]; /* allocation map */ int ulockpg; /* count of user lock available */ }semalloc; Page lkpgheader[NSEMPG]; +#define lhash(laddr) ((int)laddr>>2)&(((NSEMPG-ULOCKPG)*(BY2PG>>2))-1) void lockinit(void) { memset(semalloc.bmap, 0, sizeof(semalloc.bmap)); - semalloc.bmap[0] = 1; - + /* + * Initialise the system semaphore hardware + */ + memset(SBSEM, 0, (NSEMPG-ULOCKPG)*BY2PG); semalloc.ulockpg = ULOCKPG; - semalloc.lock.sbsem = SBSEM; - semalloc.nextsem = SBSEM+1; - semalloc.nsem = 1; - unlock(&semalloc.lock); } -/* return the address of the next free page of locks */ -ulong* -lkpgalloc(void) -{ - uchar *p, *top; - - top = &semalloc.bmap[NSEMPG]; - for(p = semalloc.bmap; *p && p < top; p++) - ; - if(p == top) - panic("lkpgalloc"); - - *p = 1; - return (p-semalloc.bmap)*WD2PG + SBSEM; -} - -/* Moral equivalent of newpage for pages of hardware lock */ +/* Moral equivalent of newpage for pages of hardware locks */ Page* lkpage(ulong va) { @@ -103,78 +87,64 @@ lkpgfree(Page *pg) unlock(&semalloc.lock); } -/* - * If l->sbsem is zero, allocate a hardware semaphore first. - */ void -lock(Lock *l) +lock(Lock *lk) { - int i; - ulong *sbsem; - - sbsem = l->sbsem; - if(sbsem == 0){ - lock(&semalloc.lock); - if(l->sbsem == 0){ - if(semalloc.nsem == SEMPERPG){ - semalloc.nsem = 0; - semalloc.nextsem = lkpgalloc(); + int *hwsem; + int i, 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; } - l->sbsem = semalloc.nextsem; - semalloc.nextsem++; - semalloc.nsem++; - unlock(l); /* put sem in known state */ } - unlock(&semalloc.lock); - sbsem = l->sbsem; + while(lk->val && i) + i--; + if(i <= 0) + break; } - /* - * Try the fast grab first - */ - if((*sbsem&1) == 0){ - l->pc = getcallerpc(l); - return; - } - for(i=0; i<10000000; i++) - if((*sbsem&1) == 0){ - l->pc = getcallerpc(l); - return; - } - *sbsem = 0; - print("lock loop %lux pc %lux held by pc %lux\n", l, getcallerpc(l), l->pc); + print("lock loop %lux pc %lux held by pc %lux\n", lk, getcallerpc(lk), lk->pc); dumpstack(); -} +} int -canlock(Lock *l) +canlock(Lock *lk) { - ulong *sbsem; - - sbsem = l->sbsem; - if(sbsem == 0){ - lock(&semalloc.lock); - if(l->sbsem == 0){ - if(semalloc.nsem == SEMPERPG){ - semalloc.nsem = 0; - semalloc.nextsem = lkpgalloc(); + int *hwsem; + int i, 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; } - l->sbsem = semalloc.nextsem; - semalloc.nextsem++; - semalloc.nsem++; - unlock(l); /* put sem in known state */ } - unlock(&semalloc.lock); - sbsem = l->sbsem; + if(lk->val) + return 0; } - if(*sbsem & 1) - return 0; - l->pc = getcallerpc(l); - return 1; } void unlock(Lock *l) { l->pc = 0; - *l->sbsem = 0; + l->val = 0; } diff --git a/power/main.c b/power/main.c index 858c48afcfd41e61e594b55d0ce6f8e9f616db33..c381d93a8d499d5b5c55f1c4a0d21519ce8b404e 100644 --- a/power/main.c +++ b/power/main.c @@ -6,37 +6,16 @@ #include "io.h" #include "init.h" -/* - * software tlb simulation - */ -Softtlb stlb[4][STLBSIZE]; - -/* - * args passed by boot process - */ -int _argc; char **_argv; char **_env; - -/* - * arguments passed to initcode - */ -char argbuf[128]; -int argsize; - -/* - * environment variables extracted from NVRAM - */ -char consname[NAMELEN]; -char diskless[NAMELEN]; - -/* - * configuration file read by boot program - */ -char confbuf[4*1024]; - -/* - * IO board type - */ -int ioid; +Softtlb stlb[MAXMACH][STLBSIZE]; /* software tlb simulation */ +int _argc; /* args passed by boot process */ +char **_argv; +char **_env; +char argbuf[128]; /* arguments passed to initcode */ +int argsize; +char consname[NAMELEN]; /* environment vars from NVRAM */ +char diskless[NAMELEN]; +char confbuf[4*1024]; /* config file read by boot program */ +int ioid; /* IO board type */ void main(void) @@ -47,20 +26,20 @@ main(void) arginit(); confinit(); lockinit(); + xinit(); printinit(); duartspecial(0, &printq, &kbdq, 9600); + pageinit(); +xsummary(); tlbinit(); vecinit(); procinit0(); initseg(); - grpinit(); - chaninit(); clockinit(); ioboardinit(); chandevreset(); streaminit(); swapinit(); - pageinit(); userinit(); launchinit(); schedinit(); @@ -521,14 +500,14 @@ confinit(void) /* * copy configuration down from high memory */ - strcpy(confbuf, (char *)(0x80000000 + 4*1024*1024 - 4*1024)); + strcpy(confbuf, (char *)(0x80000000 + (4*MB) - BY2PG)); /* * size memory */ x = 0x12345678; for(i=4; i<128; i+=4){ - l = (long*)(KSEG1|(i*1024L*1024L)); + l = (long*)(KSEG1|(i*MB)); *l = x; wbflush(); *(ulong*)KSEG1 = *(ulong*)KSEG1; /* clear latches */ @@ -541,8 +520,11 @@ confinit(void) conf.npage = conf.npage0; conf.npage1 = 0; conf.base1 = 0; - conf.maxialloc = 16*1024*1024; + conf.upages = (conf.npage*70)/100; + i = conf.npage-conf.upages; + if(i > (12*MB)/BY2PG) + conf.upages += i - ((12*MB)/BY2PG); /* * clear MP bus error caused by sizing memory */ @@ -554,27 +536,15 @@ confinit(void) */ conf.nmach = 1; conf.nproc = 100; - conf.npgrp = conf.nproc / 4; - conf.npgenv = 4 * conf.npgrp; + conf.npgenv = 4 * conf.nproc; conf.nenv = 4 * conf.nproc; conf.nenvchar = 20 * conf.nenv; - conf.nmtab = conf.nproc; - conf.nseg = 4 * conf.nproc; - conf.npagetab = conf.nseg*3; conf.nswap = 262144; conf.nimage = 200; - conf.nchan = 20 * conf.nproc; - conf.nmntdev = conf.nproc; - conf.nmntbuf = conf.nproc; - conf.nmnthdr = conf.nproc; conf.nstream = 2 * conf.nproc; - conf.nalarm = 2500; - conf.nmount = 500; - conf.nsrv = 20; conf.nurp = 25; conf.dkif = 1; conf.nqueue = 5 * conf.nstream; - conf.nblock = 10 * conf.nstream; conf.ipif = 8; conf.ip = 64; conf.arp = 32; @@ -582,7 +552,6 @@ confinit(void) confread(); - conf.npipe = conf.nstream/2; /* must be after confread */ if(conf.nmach > MAXMACH) panic("confinit"); @@ -597,7 +566,8 @@ confinit(void) * * also grab any environment variables that might be useful */ -struct{ +struct +{ char *name; char *val; }bootenv[] = { @@ -718,7 +688,7 @@ lanceIO3setup(Lance *lp) * space */ len = (lp->nrrb + lp->ntrb)*sizeof(Etherpkt); - lp->rp = (Etherpkt*)ialloc(len , 1); + lp->rp = (Etherpkt*)xspanalloc(len , BY2PG, 0); lp->tp = lp->rp + lp->nrrb; x = (ulong)lp->rp; lp->lrp = (Etherpkt*)(x & 0xFFF); diff --git a/power/mem.h b/power/mem.h index 63d80fe332fea63ea89a8aaee2f9091082cc2f15..dc8aa655f246d43353b4d53b44429a821de717e4 100644 --- a/power/mem.h +++ b/power/mem.h @@ -14,6 +14,7 @@ #define PGSHIFT 12 /* log(BY2PG) */ #define PGROUND(s) (((s)+(BY2PG-1))&~(BY2PG-1)) #define ICACHESIZE (64*1024) /* Power series */ +#define MB (1024*1024) #define MAXMACH 4 /* max # cpus system can run */ diff --git a/ss/main.c b/ss/main.c index 45152f076969eddaacc329a6adefb87f63df1907..4d2f4380be9c0b7a2e88f6376afae372b1fd5da1 100644 --- a/ss/main.c +++ b/ss/main.c @@ -215,11 +215,6 @@ confinit(void) conf.npgenv = 200*mul; conf.nstream = 40 + 32*mul; conf.nqueue = 5 * conf.nstream; - conf.nsrv = 16*mul; /* was 32 */ - conf.nbitmap = 300*mul; - conf.nbitbyte = 300*1024*mul; - conf.nfont = 10*mul; - conf.nsubfont = 10*mul; conf.nurp = 32; conf.nasync = 1; conf.copymode = 0; /* copy on write */ @@ -276,7 +271,7 @@ lancesetup(Lance *lp) */ i = (lp->nrrb+lp->ntrb)*sizeof(Etherpkt); i = (i+(BY2PG-1))/BY2PG; - pa = (ulong)ialloc(i*BY2PG, 1)&~KZERO; + pa = (ulong)xspanalloc(i*BY2PG, BY2PG, 0)&~KZERO; va = 0; for(j=i-1; j>=0; j--){ k = kmappa(pa+j*BY2PG, PTEMAINMEM|PTENOCACHE);