M gnot/dat.h => gnot/dat.h +0 -4
@@ 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 */
M gnot/main.c => gnot/main.c +9 -18
@@ 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 */
M gnot/mem.h => gnot/mem.h +1 -0
@@ 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 */
M gnot/mmu.c => gnot/mmu.c +2 -2
@@ 99,9 99,9 @@ kmapinit(void)
print("%lud free map registers\n", e-i);
kmapalloc.free = 0;
- for(k=&kmapalloc.arena[i]; i<e; i++,k++){
+ for(k=&kmapalloc.arena[i]; i < e; i++){
k->va = i*BY2PG|KZERO;
- kunmap(k);
+ kunmap(k++);
}
}
M pc/dat.h => pc/dat.h +0 -4
@@ 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 */
M pc/main.c => pc/main.c +0 -4
@@ 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;
M port/alloc.c => port/alloc.c +4 -16
@@ 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;
}
M port/devbit.c => port/devbit.c +323 -259
@@ 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<<src->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 || miny<src->r.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; y<maxy; y++){
- q = (uchar*)gaddr(src, Pt(src->r.min.x, y));
- q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
- if(bit.rid == 0 && flipping) /* flip bits */
- for(x=0; x<l; x++)
- *p++ = ~(*q++);
- else
- for(x=0; x<l; x++)
- *p++ = *q++;
- n += l;
- }
- if(off)
- cursoron(1);
- bit.rid = -1;
- break;
- }
- error(Ebadblt);
-
- case Qscreen:
+ return 10;
+ }
+ if(c->qid.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<<src->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 || miny<src->r.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; y<maxy; y++){
+ q = (uchar*)gaddr(src, Pt(src->r.min.x, y));
+ q += (src->r.min.x&((sizeof(ulong))*ws-1))/ws;
+ if(bit.rid == 0 && flipping) /* flip bits */
+ for(x=0; x<l; x++)
+ *p++ = ~(*q++);
+ else
+ for(x=0; x<l; x++)
+ *p++ = *q++;
+ n += l;
+ }
+ if(off)
+ cursoron(1);
+ bit.rid = -1;
}
+ poperror();
+ qunlock(&bit);
return n;
}
@@ 598,7 611,9 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
error(Egreg);
isoff = 0;
+ qlock(&bit);
if(waserror()){
+ qunlock(&bit);
if(isoff)
cursoron(1);
nexterror();
@@ 1001,48 1016,6 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
m -= 11;
break;
- case 's':
- /*
- * subfstring
- * 's' 1
- * id 2
- * pt 8
- * subfont id 2
- * code 2
- * string n (null terminated)
- */
- if(m < 16)
- error(Ebadblt);
- v = GSHORT(p+1);
- if(v<0 || v>=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; a<ea; a++){
+ if(a->words == 0)
+ continue;
+ if(a->wfree+HDR+nw <= a->words+a->nwords)
+ goto found;
}
+
+ /* compact and try again */
+ bitcompact();
+ aa = 0;
+ for(a=bit.arena; a<ea; a++){
+ if(a->words == 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);
}
@@ 1370,6 1391,13 @@ subfontfree(GSubfont *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)
{
int full;
@@ 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; a<ea; a++){
+ if(a->words == 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(na<ea && p1<a->words+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; a<ea && a->words; a++)
+ if(a->nbusy == 0)
+ arenafree(a);
}
void
M port/devconc.c => port/devconc.c +1 -1
@@ 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);
}
M port/devdk.c => port/devdk.c +19 -33
@@ 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);
}
M port/devenv.c => port/devenv.c +1 -1
@@ 42,7 42,7 @@ void evfree(Envval*);
void
envreset(void)
{
- evscratch = ialloc(BY2PG, 0);
+ evscratch = xalloc(BY2PG);
}
void
M port/devip.c => port/devip.c +4 -4
@@ 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]);
}
M port/devmux.c => port/devmux.c +1 -1
@@ 127,7 127,7 @@ muxinit(void)
void
muxreset(void)
{
- muxes = ialloc(conf.nmux*sizeof(Mux), 0);
+ muxes = xalloc(conf.nmux*sizeof(Mux));
}
Chan *
M port/devscc.c => port/devscc.c +2 -2
@@ 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);
}
M port/devsrv.c => port/devsrv.c +84 -59
@@ 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; i<conf.nsrv; i++){
- if(srv[i].chan == 0){
- if(j == -1)
- j = i;
- }
- else if(strcmp(name, srv[i].name) == 0)
- error(Einuse);
- }
- if(j == -1)
- exhausted("server slots");
- sp = &srv[j];
- sp->chan = 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;
}
M port/error.h => port/error.h +1 -1
@@ 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 */
M port/page.c => port/page.c +1 -1
@@ 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;
M port/portfns.h => port/portfns.h +249 -251
@@ 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*);
M port/proc.c => port/proc.c +2 -2
@@ 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;
M port/stasync.c => port/stasync.c +9 -5
@@ 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));
}
/*
M port/stip.c => port/stip.c +1 -1
@@ 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++)
M port/stlapd.c => port/stlapd.c +33 -30
@@ 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
M port/sturp.c => port/sturp.c +1 -1
@@ 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
M port/sysproc.c => port/sysproc.c +5 -106
@@ 8,7 8,6 @@
#include <a.out.h>
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)) {
@@ 522,36 493,6 @@ syswait(ulong *arg)
}
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)
{
USED(arg);
@@ 572,48 513,6 @@ syserrstr(ulong *arg)
}
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)
{
USED(arg);
M port/systab.h => port/systab.h +6 -6
@@ 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,
M power/conf.h => power/conf.h +0 -13
@@ 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 },
M power/dat.h => power/dat.h +2 -14
@@ 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 */
M power/devcyc.c => power/devcyc.c +0 -1
@@ 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"
M power/devduart.c => power/devduart.c +3 -3
@@ 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;
M power/fns.h => power/fns.h +2 -0
@@ 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)
M power/lock.c => power/lock.c +54 -84
@@ 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;
}
M power/main.c => power/main.c +23 -53
@@ 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);
M power/mem.h => power/mem.h +1 -0
@@ 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 */
M ss/main.c => ss/main.c +1 -6
@@ 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);