M gnot/dat.h => gnot/dat.h +1 -14
@@ 68,30 68,20 @@ struct Conf
{
int nmach; /* processors */
int nproc; /* processes */
- int npgrp; /* process groups */
ulong npage0; /* total physical pages of memory, bank 0 */
ulong npage1; /* total physical pages of memory, bank 1 */
ulong npage;
ulong base0; /* base of bank 0 */
ulong base1; /* base of bank 1 */
- 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 blocks */
- int nalarm; /* alarms */
- int nchan; /* channels */
int nenv; /* distinct environment values */
int nenvchar; /* environment text storage */
int npgenv; /* environment files per process group */
- int nmtab; /* mounted-upon channels per process group */
- int nmount; /* mounts */
- int nmntdev; /* mounted devices (devmnt.c) */
- int nmntbuf; /* buffers for devmnt.c messages */
- int nmnthdr; /* headers for devmnt.c messages */
int nmux; /* number of mux devices */
int nstream; /* streams */
int nqueue; /* stream queues */
- int nblock; /* stream blocks */
int nsrv; /* public servers (devsrv.c) */
int nbitmap; /* bitmap structs (devbit.c) */
int nbitbyte; /* bytes of bitmap data (devbit.c) */
@@ 99,12 89,9 @@ struct Conf
int nsubfont; /* Gsubfont structs (devbit.c) */
int nurp; /* max urp conversations */
int nasync; /* number of async protocol modules */
- int npipe; /* number of pipes */
- int nservice; /* number of services */
int nfsyschan; /* number of filsys open channels */
int nisdn; /* number of isdn interfaces */
int nlapd; /* number of dragnet protocol modules */
- ulong maxialloc; /* maximum bytes used by ialloc */
int copymode; /* 0 is copy on write, 1 is copy on reference */
int portispaged; /* ??? */
int cntrlp; /* panic on ^P */
M gnot/devport.c => gnot/devport.c +41 -20
@@ 11,7 11,15 @@
#define ROMADDR 0x40000000
#define ROMSIZE ((256*1024)/8)
-enum {
+#define P_oper(sel, inst) (P_qlock(sel), inst, P_qunlock(sel))
+#define P_qlock(sel) (sel >= 0 ? (qlock(&portpage), \
+ PORTSELECT = portpage.select = sel) : -1)
+#define P_qunlock(sel) (sel >= 0 ? (qunlock(&portpage),0) : -1)
+#define P_read(sel, addr, val, type) P_oper(sel, val = *(type *)(PORT+addr))
+#define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val)
+
+enum
+{
Qdir,
Qdata,
Qrom
@@ 24,6 32,11 @@ Dirtab portdir[]={
#define NPORT (sizeof portdir/sizeof(Dirtab))
+#define Nportservice 8
+static int (*portservice[Nportservice])(void);
+static Portpage portpage;
+static Lock intrlock;
+
int
portprobe(char *what, int select, int addr, int rw, long val)
{
@@ 33,17 46,23 @@ portprobe(char *what, int select, int addr, int rw, long val)
P_qlock(select);
switch (rw) {
case -1:
- val = *(uchar *)(PORT+addr); break;
+ val = *(uchar *)(PORT+addr);
+ break;
case -2:
- val = *(ushort *)(PORT+addr); break;
+ val = *(ushort *)(PORT+addr);
+ break;
case -4:
- val = *(long *)(PORT+addr); break;
+ val = *(long *)(PORT+addr);
+ break;
case 1:
- *(uchar *)(PORT+addr) = val; break;
+ *(uchar *)(PORT+addr) = val;
+ break;
case 2:
- *(ushort *)(PORT+addr) = val; break;
+ *(ushort *)(PORT+addr) = val;
+ break;
case 4:
- *(long *)(PORT+addr) = val; break;
+ *(long *)(PORT+addr) = val;
+ break;
default:
panic("portprobe");
}
@@ 68,7 87,8 @@ portreset(void)
void
portinit(void)
-{}
+{
+}
Chan *
portattach(char *param)
@@ 108,7 128,8 @@ portcreate(Chan *c, char *name, int omode, ulong perm)
void
portclose(Chan *c)
-{}
+{
+}
long
portread(Chan *c, char *a, long n, ulong offset)
@@ 167,9 188,11 @@ portwrite(Chan *c, char *a, long n, ulong offset)
case 1:
PORT[k] = *a; break;
case 2:
- *(short *)(PORT+k) = *(short *)a; break;
+ *(short *)(PORT+k) = *(short *)a;
+ break;
case 4:
- *(long *)(PORT+k) = *(long *)a; break;
+ *(long *)(PORT+k) = *(long *)a;
+ break;
default:
P_qunlock(s);
error(Ebadarg);
@@ 185,27 208,23 @@ portwrite(Chan *c, char *a, long n, ulong offset)
void
portremove(Chan *c)
{
+ USED(c);
error(Eperm);
}
void
portwstat(Chan *c, char *dp)
{
+ USED(c, dp);
error(Eperm);
}
-#define Nportservice 8
-int (*portservice[Nportservice])(void);
-
-Portpage portpage;
-
-Lock intrlock;
-
void
addportintr(int (*f)(void))
{
int s = splhi();
int (**p)(void);
+
lock(&intrlock);
for (p=portservice; *p; p++)
if (*p == f)
@@ 221,13 240,15 @@ out:
void
devportintr(void)
{
- int (**p)(void); int i = 0;
+ int (**p)(void);
+ int i = 0;
+
for (p=portservice; *p; p++)
i |= (**p)();
+
if (!i)
/*putstring("spurious portintr\n");*/
panic("portintr");
if (portpage.select >= 0)
PORTSELECT = portpage.select;
-
}
M gnot/fns.h => gnot/fns.h +2 -6
@@ 1,11 1,5 @@
#include "../port/portfns.h"
-#define P_oper(sel, inst) (P_qlock(sel), inst, P_qunlock(sel))
-#define P_qlock(sel) (sel >= 0 ? (qlock(&portpage), PORTSELECT = portpage.select = sel) : -1)
-#define P_qunlock(sel) (sel >= 0 ? (qunlock(&portpage),0) : -1)
-#define P_read(sel, addr, val, type) P_oper(sel, val = *(type *)(PORT+addr))
-#define P_write(sel, addr, val, type) P_oper(sel, *(type *)(PORT+addr) = val)
-
void addportintr(int (*)(void));
void bootargs(ulong);
void clearmmucache(void);
@@ 63,3 57,5 @@ void touser(void*);
#define waserror() (u->nerrlab++, setlabel(&u->errlab[u->nerrlab-1]))
#define kmapperm(x) kmap(x)
#define getcallerpc(x) (*(ulong*)(x))
+#define KADDR(a) ((void*)((ulong)(a)|KZERO))
+#define PADDR(a) ((ulong)(a)&~KZERO)
M gnot/main.c => gnot/main.c +3 -15
@@ 312,27 312,17 @@ confinit(void)
conf.npage1 = (bank[1]*1024*1024)/BY2PG;
conf.base1 = 16*1024*1024;
conf.npage = conf.npage0+conf.npage1;
- conf.maxialloc = (4*1024*1024-256*1024-BY2PG);
+ conf.upages = (conf.npage*70)/100;
+
mul = 1 + (conf.npage1>0);
conf.nproc = 50*mul;
- conf.nseg = conf.nproc*4;
- conf.npagetab = conf.nseg*2;
conf.nswap = 4096;
conf.nimage = 50;
- conf.npgrp = 20*mul;
- conf.nalarm = 1000;
- conf.nchan = 200*mul;
conf.nenv = 100*mul;
conf.nenvchar = 8000*mul;
conf.npgenv = 200*mul;
- conf.nmtab = 50*mul;
- conf.nmount = 80*mul;
- conf.nmntdev = 10*mul;
- conf.nmntbuf = conf.nmntdev+5;
- conf.nmnthdr = 2*conf.nmntdev;
conf.nstream = 40 + 32*mul;
conf.nqueue = 5 * conf.nstream;
- conf.nblock = 24 * conf.nstream;
conf.nsrv = 16*mul; /* was 32 */
conf.nbitmap = 300*mul;
conf.nbitbyte = 300*1024*mul;
@@ 343,13 333,11 @@ confinit(void)
conf.nfont = 10*mul;
conf.nurp = 32;
conf.nasync = 1;
- conf.npipe = conf.nstream/2;
- conf.nservice = 3*mul; /* was conf.nproc/5 */
- conf.nfsyschan = 31 + conf.nchan/20;
conf.copymode = 0; /* copy on write */
conf.portispaged = 0;
conf.cntrlp = 0;
conf.dkif = 2;
+
confinit1(mul);
}
M port/alloc.c => port/alloc.c +43 -10
@@ 4,9 4,18 @@
#include "dat.h"
#include "fns.h"
+/*
+ * Plan 9 has two kernel allocators, the x... routines provide a first
+ * fit hole allocator which should be used for permanent or large structures.
+ * Routines are provided to allocate aligned memory which does not cross
+ * arbitrary 2^n boundaries. A second allocator malloc, smalloc, free is
+ * a 2n bucket allocator which steals from the x routines. This should
+ * be used for small frequently used structures.
+ */
+
#define nil ((void*)0)
-#define datoff ((ulong)&((Xhdr*)0)->data)
-#define bdatoff ((ulong)&((Bucket*)0)->data)
+#define datoff ((ulong)((Xhdr*)0)->data)
+#define bdatoff ((ulong)((Bucket*)0)->data)
enum
{
@@ 14,6 23,7 @@ enum
Nhole = 128,
Magichole = 0xDeadBabe,
Magic2n = 0xFeedBeef,
+ Spanlist = 64,
};
typedef struct Hole Hole;
@@ 75,14 85,7 @@ ialloc(ulong size, int align)
p &= ~(BY2PG-1);
return (void*)p;
}
-
- return xalloc(size);
-}
-
-void*
-iallocspan(ulong size, int quanta, ulong span)
-{
- return ialloc(size, quanta);
+ return xalloc(size);;
}
void
@@ 127,6 130,36 @@ xinit(void)
palloc.np1 = np1;
}
+/*
+ * NB. spanalloc memory will cause a panic if free'd
+ */
+void*
+xspanalloc(ulong size, int align, ulong span)
+{
+ int i, j;
+ ulong a, p;
+ ulong ptr[Spanlist];
+
+ span = ~(span-1);
+ for(i = 0; i < Spanlist; i++) {
+ p = (ulong)xalloc(size+align);
+ if(p == 0)
+ panic("xspanalloc: size %d align %d span %d", size, align, span);
+
+ a = p+align;
+ a &= ~(align-1);
+ if((a&span) == ((a+size)&span)) {
+ for(j = 0; j < i; j++)
+ xfree((void*)ptr[j]);
+
+ return (void*)a;
+ }
+ ptr[i] = p;
+ }
+ panic("xspanalloc: spanlist");
+ return 0;
+}
+
void*
xalloc(ulong size)
{
M port/devbit.c => port/devbit.c +180 -149
@@ 37,23 37,26 @@ int flipping; /* are flip tables being used to transform Fcodes? */
*/
/*
- * Some fields in GBitmaps are overloaded:
- * ldepth = -1 means free.
- * base is next pointer when free.
* 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.
+ * followed by N blocks. 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.
*/
struct
{
Ref;
- GBitmap *map; /* arena */
- GBitmap *free; /* free list */
+ 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; /* arena; looked up linearly BUG */
- GSubfont *subfont; /* arena; looked up linearly BUG */
+ GFont **font; /* indexed array */
+ int nfont; /* number allocated */
+ GSubfont**subfont; /* indexed array */
+ int nsubfont; /* number allocated */
int lastid; /* last allocated bitmap id */
int lastsubfid; /* last allocated subfont id */
int lastfid; /* last allocated font id */
@@ 64,10 67,13 @@ struct
int mid; /* colormap read bitmap id */
}bit;
+#define DMAP 32 /* delta increase in size of arrays */
#define FREE 0x80000000
void bitcompact(void);
-GBitmap*bitalloc(Rectangle, int);
+int bitalloc(Rectangle, int);
void bitfree(GBitmap*);
+void fontfree(GFont*);
+void subfontfree(GSubfont*);
void bitstring(GBitmap*, Point, GFont*, uchar*, long, Fcode);
void bitloadchar(GFont*, int, GSubfont*, int);
extern GBitmap gscreen;
@@ 142,7 148,7 @@ Dirtab bitdir[]={
};
#define NBIT (sizeof bitdir/sizeof(Dirtab))
-#define NINFO 257
+#define NINFO 8192
void
bitreset(void)
@@ 151,31 157,22 @@ bitreset(void)
GBitmap *bp;
ulong r;
- bit.map = ialloc(conf.nbitmap * sizeof(GBitmap), 0);
- for(i=0,bp=bit.map; i<conf.nbitmap; i++,bp++){
- bp->ldepth = -1;
- bp->base = (ulong*)(bp+1);
- }
- bp--;
- bp->base = 0;
- bit.map[0] = gscreen; /* bitmap 0 is screen */
+ bit.map = smalloc(DMAP*sizeof(GBitmap*));
+ bit.nmap = DMAP;
getcolor(0, &r, &r, &r);
if(r == 0)
flipping = 1;
- bit.free = bit.map+1;
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.subfont = ialloc(conf.nsubfont * sizeof(GSubfont), 0);
- bit.subfont[0] = *defont;
- bit.font = ialloc(conf.nfont * sizeof(GFont), 0);
- for(i=1; i<conf.nsubfont; i++)
- bit.subfont[i].info = ialloc((NINFO+1)*sizeof(Fontchar), 0);
- for(i=0; i<conf.nfont; i++)
- bit.font[i].ldepth = -1;
+ bit.font = smalloc(DMAP*sizeof(GFont*));
+ bit.nfont = DMAP;
+ bit.subfont = smalloc(DMAP*sizeof(GSubfont*));
+ bit.nsubfont = DMAP;
Cursortocursor(&arrow);
}
@@ 186,7 183,7 @@ bitinit(void)
unlock(&bit);
if(gscreen.ldepth > 3)
cursorback.ldepth = 0;
- else {
+ else{
cursorback.ldepth = gscreen.ldepth;
cursorback.width = ((16 << gscreen.ldepth) + 31) >> 5;
}
@@ 196,7 193,6 @@ bitinit(void)
Chan*
bitattach(char *spec)
{
- bit.map[0] = gscreen; /* bitmap 0 is screen */
return devattach('b', spec);
}
@@ 221,9 217,11 @@ bitstat(Chan *c, char *db)
devstat(c, db, bitdir, NBIT, devgen);
}
-Chan *
+Chan*
bitopen(Chan *c, int omode)
{
+ GBitmap *b;
+
if(c->qid.path == CHDIR){
if(omode != OREAD)
error(Eperm);
@@ 233,7 231,10 @@ bitopen(Chan *c, int omode)
unlock(&bit);
error(Einuse);
}
- bit.map[0].clipr = gscreen.clipr;
+ b = smalloc(sizeof(GBitmap));
+ *b = gscreen;
+ bit.map[0] = b; /* bitmap 0 is screen */
+ bit.subfont[0] = defont; /* subfont 0 is default */
bit.lastid = -1;
bit.lastfid = -1;
bit.lastsubfid = -1;
@@ 275,24 276,43 @@ bitwstat(Chan *c, char *db)
void
bitclose(Chan *c)
{
- int i;
- GBitmap *bp;
- GSubfont *fp;
- GFont *ffp;
+ GBitmap *b, **bp, **ebp;
+ GSubfont *s, **sp, **esp;
+ GFont *f, **fp, **efp;
if(c->qid.path!=CHDIR && (c->flag&COPEN)){
lock(&bit);
if(--bit.ref == 0){
- for(i=1,bp=&bit.map[1]; i<conf.nbitmap; i++,bp++)
- if(bp->ldepth >= 0)
- bitfree(bp);
- for(i=1,fp=&bit.subfont[1]; i<conf.nsubfont; i++,fp++)
- fp->bits = 0;
- for(i=0,ffp=&bit.font[0]; i<conf.nfont; i++,ffp++){
- ffp->b = 0;
- ffp->ldepth = -1;
+ /* 0th bitmap, screen, has no special storage */
+ bp = bit.map;
+ free(*bp);
+ *bp = 0;
+ ebp = &bit.map[bit.nmap];
+ bp++;
+ for(; bp<ebp; bp++){
+ b = *bp;
+ if(b){
+ bitfree(b);
+ *bp = 0;
+ }
+ }
+ /* 0th subfont, defont, points to real storage */
+ esp = &bit.subfont[bit.nsubfont];
+ for(sp=&bit.subfont[1]; sp<esp; sp++){
+ s = *sp;
+ if(s){
+ subfontfree(s);
+ *sp = 0;
+ }
+ }
+ efp = &bit.font[bit.nfont];
+ for(fp=bit.font; fp<efp; fp++){
+ f = *fp;
+ if(f){
+ fontfree(f);
+ *fp = 0;
+ }
}
-bit.font[0].ldepth=0;/*BUG */
}
unlock(&bit);
}
@@ 440,7 460,10 @@ bitread(Chan *c, void *va, long n, ulong offset)
* read colormap:
* data 12*(2**bitmapdepth)
*/
- l = (1<<bit.map[bit.mid].ldepth);
+ src = bit.map[bit.mid];
+ if(src == 0)
+ error(Ebadbitmap);
+ l = (1<<src->ldepth);
nw = 1 << l;
if(n < 12*nw)
error(Ebadblt);
@@ 467,8 490,8 @@ bitread(Chan *c, void *va, long n, ulong offset)
* read bitmap:
* data bytewidth*(maxy-miny)
*/
- src = &bit.map[bit.rid];
- if(src->ldepth<0)
+ src = bit.map[bit.rid];
+ if(src == 0)
error(Ebadbitmap);
off = 0;
if(bit.rid == 0)
@@ 558,15 581,15 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
uchar *p, *q;
long m, v, miny, maxy, minx, maxx, t, x, y;
ulong l, nw, ws, rv;
- int off, isoff, i, ok;
+ int off, isoff, i, j, ok;
Point pt, pt1, pt2;
Rectangle rect;
Cursor curs;
Fcode fc;
Fontchar *fcp;
- GBitmap *bp, *src, *dst;
- GSubfont *f;
- GFont *ff;
+ GBitmap *b, *src, *dst, *bp;
+ GSubfont *f, **fp;
+ GFont *ff, **ffp;
if(c->qid.path == CHDIR)
error(Eisdir);
@@ 582,6 605,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
}
p = va;
m = n;
+ SET(src, dst, f, ff);
while(m > 0)
switch(*p){
default:
@@ 607,8 631,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
rect.max.y = GLONG(p+14);
if(Dx(rect) < 0 || Dy(rect) < 0)
error(Ebadblt);
- bp = bitalloc(rect, v);
- bit.lastid = bp-bit.map;
+ bit.lastid = bitalloc(rect, v);
m -= 18;
p += 18;
break;
@@ 627,8 650,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
error(Ebadblt);
fc = GSHORT(p+29) & 0xF;
v = GSHORT(p+11);
- src = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || src->ldepth < 0)
+ if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
if(v == 0){
@@ 637,8 659,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
off = 1;
}
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth < 0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
if(v == 0){
if(flipping)
@@ 703,10 724,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 3)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
bitfree(dst);
+ bit.map[v] = 0;
m -= 3;
p += 3;
break;
@@ 720,10 741,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 3)
error(Ebadblt);
v = GSHORT(p+1);
- f = &bit.subfont[v];
- if(v<0 || v>=conf.nsubfont || f->bits==0)
+ if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
error(Ebadfont);
- f->bits = 0;
+ subfontfree(f);
+ bit.subfont[v] = 0;
m -= 3;
p += 3;
break;
@@ 737,13 758,10 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 3)
error(Ebadblt);
v = GSHORT(p+1);
- ff = &bit.font[v];
- if(v<0 || v>=conf.nfont || ff->ldepth<0)
+ if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
error(Ebadfont);
- if(ff->b)
- bitfree(ff->b);
- ff->b = 0;
- ff->ldepth = -1;
+ fontfree(ff);
+ bit.font[v] = 0;
m -= 3;
p += 3;
break;
@@ 776,23 794,28 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
v = GSHORT(p+1);
if(v<0 || v>NINFO || m<7+6*(v+1)) /* BUG */
error(Ebadblt);
- for(i=1; i<conf.nsubfont; i++)
- if(bit.subfont[i].bits == 0)
+ for(i=1; i<bit.nsubfont; i++)
+ if(bit.subfont[i] == 0)
goto subfontfound;
- error(Enofont);
+ fp = bit.subfont;
+ bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(GSubfont*));
+ memmove(bit.subfont, fp, bit.nsubfont*sizeof(GSubfont*));
+ free(fp);
+ bit.nsubfont += DMAP;
subfontfound:
- f = &bit.subfont[i];
+ f = smalloc(sizeof(GSubfont));
+ bit.subfont[i] = f;
+ f->info = smalloc((v+1)*sizeof(Fontchar));
f->n = v;
f->height = p[3];
f->ascent = p[4];
v = GSHORT(p+5);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
m -= 7;
p += 7;
fcp = f->info;
- for(i=0; i<=f->n; i++,fcp++){
+ for(j=0; j<=f->n; j++,fcp++){
fcp->x = GSHORT(p);
fcp->top = p[2];
fcp->bottom = p[3];
@@ 802,7 825,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
p += 6;
m -= 6;
}
- bit.lastsubfid = f - bit.subfont;
+ bit.lastsubfid = i;
f->bits = dst;
break;
@@ 820,8 843,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 22)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
fc = GSHORT(p+20) & 0xF;
@@ 854,8 876,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 3)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
bit.mid = v;
m -= 3;
@@ 876,12 897,18 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
v = GSHORT(p+3);
if(v < 0)
error(Ebadblt);
- for(i=0; i<conf.nfont; i++)
- if(bit.font[i].ldepth < 0)
+ for(i=0; i<bit.nfont; i++)
+ if(bit.font[i] == 0)
goto fontfound;
- error(Enofont);
+ ffp = bit.font;
+ bit.font = smalloc((bit.nfont+DMAP)*sizeof(GFont*));
+ memmove(bit.font, ffp, bit.nfont*sizeof(GFont*));
+ free(ffp);
+ bit.nfont += DMAP;
fontfound:
- ff = &bit.font[i];
+ ff = smalloc(sizeof(GFont));
+ bit.font[i] = ff;
+ ff = bit.font[i];
ff->height = p[1];
ff->ascent = p[2];
ff->ldepth = v;
@@ 889,7 916,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
ff->b = 0;
m -= 5;
p += 5;
- bit.lastfid = ff - bit.font;
+ bit.lastfid = i;
break;
case 'p':
@@ 905,8 932,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 14)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
fc = GSHORT(p+12) & 0xF;
@@ 937,8 963,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 19)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
rect.min.x = GLONG(p+3);
rect.min.y = GLONG(p+7);
@@ 963,8 988,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 11)
error(Ebadblt);
v = GSHORT(p+1);
- src = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || src->ldepth<0)
+ if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
error(Ebadbitmap);
miny = GLONG(p+3);
maxy = GLONG(p+7);
@@ 990,8 1014,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 16)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
fc = GSHORT(p+13) & 0xF;
@@ 1003,8 1026,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
pt.x = GLONG(p+3);
pt.y = GLONG(p+7);
v = GSHORT(p+11);
- f = &bit.subfont[v];
- if(v<0 || v>=conf.nsubfont || f->bits==0 || f->bits->ldepth<0)
+ if(v<0 || v>=bit.nsubfont || (f=bit.subfont[v])==0)
error(Ebadblt);
p += 15;
m -= 15;
@@ 1033,8 1055,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 23)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
fc = GSHORT(p+21) & 0xF;
@@ 1048,8 1069,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
rect.max.x = GLONG(p+11);
rect.max.y = GLONG(p+15);
v = GSHORT(p+19);
- src = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || src->ldepth<0)
+ if(v<0 || v>=bit.nmap || (src=bit.map[v])==0)
error(Ebadbitmap);
if(off && !isoff){
cursoroff(1);
@@ 1074,8 1094,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 17)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
fc = GSHORT(p+13) & 0xF;
@@ 1087,8 1106,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
pt.x = GLONG(p+3);
pt.y = GLONG(p+7);
v = GSHORT(p+11);
- ff = &bit.font[v];
- if(v<0 || v>=conf.nfont || ff->ldepth<0)
+ if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
error(Ebadblt);
l = GSHORT(p+15)*2;
p += 17;
@@ 1114,8 1132,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 5)
error(Ebadblt);
v = GSHORT(p+1);
- ff = &bit.font[v];
- if(v<0 || v>=conf.nfont || ff->ldepth<0)
+ if(v<0 || v>=bit.nfont || (ff=bit.font[v])==0)
error(Ebadblt);
/*
* memset not necessary but helps avoid
@@ 1127,7 1144,9 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
bitfree(ff->b);
ff->width = GSHORT(p+3);
ff->b = 0;
- ff->b = bitalloc(Rect(0, 0, (NFCACHE+NFLOOK)*ff->width, ff->height), ff->ldepth);
+ i = bitalloc(Rect(0, 0, (NFCACHE+NFLOOK)*ff->width, ff->height), ff->ldepth);
+ ff->b = bit.map[i];
+ bit.map[i] = 0; /* disconnect it from GBitmap space */
p += 5;
m -= 5;
break;
@@ 1144,8 1163,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 11)
error(Ebadblt);
v = GSHORT(p+1);
- dst = &bit.map[v];
- if(v<0 || v>=conf.nbitmap || dst->ldepth<0)
+ if(v<0 || v>=bit.nmap || (dst=bit.map[v])==0)
error(Ebadbitmap);
off = 0;
if(v == 0)
@@ 1216,15 1234,13 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
if(m < 9)
error(Ebadblt);
v = GSHORT(p+1);
- ff = &bit.font[v];
- if(v<0 || v>=conf.nfont || ff->ldepth<0 || ff->b==0)
+ if(v<0 || v>=conf.nfont || (ff=bit.font[v])==0)
error(Ebadblt);
l = GSHORT(p+3);
if(l >= NFCACHE+NFLOOK)
error(Ebadblt);
v = GSHORT(p+5);
- f = &bit.subfont[v];
- if(v<0 || v>=conf.nsubfont || f->bits->ldepth<0)
+ if(v<0 || v>=conf.nsubfont || (f=bit.subfont[v])==0)
error(Ebadblt);
nw = GSHORT(p+7);
if(nw >= f->n)
@@ 1249,7 1265,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
error(Ebadbitmap);
m -= 3;
p += 3;
- nw = 1 << (1 << bit.map[v].ldepth);
+ nw = 1 << (1 << gscreen.ldepth);
if(m < 12*nw)
error(Ebadblt);
ok = 1;
@@ 1273,21 1289,20 @@ bitwrite(Chan *c, void *va, long n, ulong offset)
return n;
}
-GBitmap*
+int
bitalloc(Rectangle rect, int ld)
{
- GBitmap *bp;
+ GBitmap *b, **bp, **ep;
ulong l, ws, nw;
long t;
+ int i;
- if(bit.free == 0)
- error(Enobitmap);
+print("bitalloc %lux\n", bit.wfree);
ws = 1<<(5-ld); /* pixels per word */
- if(rect.min.x >= 0) {
+ if(rect.min.x >= 0){
l = (rect.max.x+ws-1)/ws;
l -= rect.min.x/ws;
- }
- else{ /* make positive before divide */
+ }else{ /* make positive before divide */
t = (-rect.min.x)+ws-1;
t = (t/ws)*ws;
l = (t+rect.max.x+ws-1)/ws;
@@ 1298,34 1313,60 @@ bitalloc(Rectangle rect, int ld)
if(bit.wfree+2+nw > bit.words+bit.nwords)
error(Enobitstore);
}
- bp = bit.free;
- bit.free = (GBitmap*)(bp->base);
+ b = smalloc(sizeof(GBitmap));
*bit.wfree++ = nw;
- *bit.wfree++ = (ulong)bp;
- bp->base = bit.wfree;
- memset(bp->base, 0, nw*sizeof(ulong));
+ *bit.wfree++ = (ulong)b;
+ b->base = bit.wfree;
+ memset(b->base, 0, nw*sizeof(ulong));
bit.wfree += nw;
- bp->zero = l*rect.min.y;
+ b->zero = l*rect.min.y;
if(rect.min.x >= 0)
- bp->zero += rect.min.x/ws;
+ b->zero += rect.min.x/ws;
else
- bp->zero -= (-rect.min.x+ws-1)/ws;
- bp->zero = -bp->zero;
- bp->width = l;
- bp->ldepth = ld;
- bp->r = rect;
- bp->clipr = rect;
- bp->cache = 0;
- return bp;
+ b->zero -= (-rect.min.x+ws-1)/ws;
+ b->zero = -b->zero;
+ b->width = l;
+ b->ldepth = ld;
+ b->r = rect;
+ b->clipr = rect;
+ b->cache = 0;
+ /* worth doing better than linear lookup? */
+ ep = bit.map+bit.nmap;
+ for(bp=bit.map; bp<ep; bp++)
+ if(*bp == 0)
+ break;
+ if(bp == ep){
+ bp = bit.map;
+ bit.map = smalloc((bit.nmap+DMAP)*sizeof(GBitmap*));
+ memmove(bit.map, bp, bit.nmap*sizeof(GBitmap*));
+ free(bp);
+ bp = bit.map+bit.nmap;
+ bit.nmap += DMAP;
+ }
+ *bp = b;
+ return bp-bit.map;
+}
+
+void
+bitfree(GBitmap *b)
+{
+ b->base[-1] = 0;
+ free(b);
}
void
-bitfree(GBitmap *bp)
+fontfree(GFont *f)
{
- bp->base[-1] = 0;
- bp->ldepth = -1;
- bp->base = (ulong*)bit.free;
- bit.free = bp;
+ if(f->b)
+ bitfree(f->b);
+ free(f);
+}
+
+void
+subfontfree(GSubfont *s)
+{
+ free(s->info);
+ free(s);
}
void
@@ 1396,16 1437,6 @@ bitloadchar(GFont *f, int ci, GSubfont *subf, int si)
QLock bitlock;
-GBitmap*
-id2bit(int k)
-{
- GBitmap *bp;
- bp = &bit.map[k];
- if(k<0 || k>=conf.nbitmap || bp->ldepth < 0)
- error(Ebadbitmap);
- return bp;
-}
-
void
bitcompact(void)
{
M port/devlance.c => port/devlance.c +4 -10
@@ 14,10 14,6 @@ enum {
#define RSUCC(x) (((x)+1)%l.nrrb)
#define TSUCC(x) (((x)+1)%l.ntrb)
-#define NOW (MACHP(0)->ticks*MS2HZ)
-
-static int netlight;
-
/*
* Communication with the lance is via a transmit and receive ring of
* message descriptors. The Initblock contains pointers to and sizes of
@@ 238,6 234,7 @@ isclosed(void *x)
{
return ((Ethertype *)x)->q == 0;
}
+
static void
lancestclose(Queue *q)
{
@@ 286,6 283,7 @@ isobuf(void *x)
m = x;
return (MPus(m->flags)&LANCEOWNER) == 0;
}
+
static void
lanceoput(Queue *q, Block *bp)
{
@@ 549,9 547,6 @@ lancestart(int mode)
*l.rdp = INEA|INIT|STRT; /**/
}
-/*
- * set up lance directory.
- */
void
lanceinit(void)
{
@@ 561,12 556,11 @@ Chan*
lanceattach(char *spec)
{
if(l.kstarted == 0){
- kproc("lancekproc", lancekproc, 0);/**/
+ kproc("lancekproc", lancekproc, 0);
l.kstarted = 1;
lancestart(0);
print("lance ether: %.2x%.2x%.2x%.2x%.2x%.2x\n",
l.ea[0], l.ea[1], l.ea[2], l.ea[3], l.ea[4], l.ea[5]);
-
}
return devattach('l', spec);
}
@@ 643,7 637,7 @@ lancewstat(Chan *c, char *dp)
static void
lancestatsfill(Chan *c, char* p, int n)
{
- char buf[256];
+ char buf[512];
USED(c);
sprint(buf, "in: %d\nout: %d\ncrc errs %d\noverflows: %d\nframe errs %d\nbuff errs: %d\noerrs %d\naddr: %.02x:%.02x:%.02x:%.02x:%.02x:%.02x\n",
M port/devpipe.c => port/devpipe.c +53 -41
@@ 8,24 8,26 @@
#include "devtab.h"
typedef struct Pipe Pipe;
-
struct Pipe
{
Ref;
QLock;
Pipe *next;
+ ulong path;
};
-struct Pipealloc
+struct
{
Lock;
- Pipe *pipe;
- Pipe *free;
+ Pipe *pipe;
+ ulong path;
} pipealloc;
+static Pipe *getpipe(ulong);
static void pipeiput(Queue*, Block*);
static void pipeoput(Queue*, Block*);
static void pipestclose(Queue *);
+
Qinfo pipeinfo =
{
pipeiput,
@@ 35,7 37,8 @@ Qinfo pipeinfo =
"pipe"
};
-Dirtab pipedir[]={
+Dirtab pipedir[] =
+{
"data", {Sdataqid}, 0, 0600,
"ctl", {Sctlqid}, 0, 0600,
"data1", {Sdataqid}, 0, 0600,
@@ 48,19 51,9 @@ pipeinit(void)
{
}
-/*
- * allocate structures for conf.npipe pipes
- */
void
pipereset(void)
{
- Pipe *p, *ep;
-
- pipealloc.pipe = ialloc(conf.npipe * sizeof(Pipe), 0);
- ep = &pipealloc.pipe[conf.npipe-1];
- for(p = pipealloc.pipe; p < ep; p++)
- p->next = p+1;
- pipealloc.free = pipealloc.pipe;
}
/*
@@ 73,20 66,16 @@ pipeattach(char *spec)
Chan *c;
c = devattach('|', spec);
+ p = smalloc(sizeof(Pipe));
+ p->ref = 1;
lock(&pipealloc);
- if(pipealloc.free == 0){
- unlock(&pipealloc);
- close(c);
- exhausted("pipes");
- }
- p = pipealloc.free;
- pipealloc.free = p->next;
- if(incref(p) != 1)
- panic("pipeattach");
+ p->path = ++pipealloc.path;
+ p->next = pipealloc.pipe;
+ pipealloc.pipe = p;
unlock(&pipealloc);
- c->qid = (Qid){CHDIR|STREAMQID(2*(p - pipealloc.pipe), 0), 0};
+ c->qid = (Qid){CHDIR|STREAMQID(2*p->path, 0), 0};
c->dev = 0;
return c;
}
@@ 96,7 85,7 @@ pipeclone(Chan *c, Chan *nc)
{
Pipe *p;
- p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
+ p = getpipe(STREAMID(c->qid.path)/2);
nc = devclone(c, nc);
if(incref(p) <= 1)
panic("pipeclone");
@@ 138,6 127,7 @@ Chan *
pipeopen(Chan *c, int omode)
{
Pipe *p;
+ int other;
Stream *local, *remote;
if(c->qid.path & CHDIR){
@@ 149,7 139,7 @@ pipeopen(Chan *c, int omode)
return c;
}
- p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
+ p = getpipe(STREAMID(c->qid.path)/2);
if(waserror()){
qunlock(p);
nexterror();
@@ 161,7 151,8 @@ pipeopen(Chan *c, int omode)
/*
* first open, create the other end also
*/
- remote = streamnew(c->type, c->dev, STREAMID(c->qid.path)^1, &pipeinfo,1);
+ other = STREAMID(c->qid.path)^1;
+ remote = streamnew(c->type, c->dev, other, &pipeinfo,1);
/*
* connect the device ends of both streams
@@ 170,7 161,9 @@ pipeopen(Chan *c, int omode)
remote->devq->ptr = local;
local->devq->other->next = remote->devq;
remote->devq->other->next = local->devq;
- } else if(local->opens == 1){
+ }
+ else
+ if(local->opens == 1){
/*
* keep other side around till last close of this side
*/
@@ 209,10 202,10 @@ pipewstat(Chan *c, char *db)
void
pipeclose(Chan *c)
{
- Pipe *p;
+ Pipe *p, *f, **l;
Stream *remote;
- p = &pipealloc.pipe[STREAMID(c->qid.path)/2];
+ p = getpipe(STREAMID(c->qid.path)/2);
/*
* take care of local and remote streams
@@ 232,12 225,17 @@ pipeclose(Chan *c)
*/
if(decref(p) == 0){
lock(&pipealloc);
- p->next = pipealloc.free;
- pipealloc.free = p;
+ l = &pipealloc.pipe;
+ for(f = *l; f; f = f->next) {
+ if(f == p) {
+ *l = p->next;
+ break;
+ }
+ l = &p->next;
+ }
unlock(&pipealloc);
+ free(p);
}
- if(p->ref < 0)
- panic("pipeexit");
}
long
@@ 245,8 243,8 @@ piperead(Chan *c, void *va, long n, ulong offset)
{
if(c->qid.path & CHDIR)
return devdirread(c, va, n, pipedir, NPIPEDIR, pipegen);
- else
- return streamread(c, va, n);
+
+ return streamread(c, va, n);
}
/*
@@ 256,7 254,7 @@ piperead(Chan *c, void *va, long n, ulong offset)
long
pipewrite(Chan *c, void *va, long n, ulong offset)
{
- if(waserror()){
+ if(waserror()) {
postnote(u->p, 1, "sys: write on closed pipe", NExit);
error(Egreg);
}
@@ 266,9 264,6 @@ pipewrite(Chan *c, void *va, long n, ulong offset)
}
/*
- * stream stuff
- */
-/*
* send a block up stream to the process.
* sleep untill there's room upstream.
*/
@@ 312,3 307,20 @@ pipestclose(Queue *q)
bp->type = M_HANGUP;
PUTNEXT(q, bp);
}
+
+Pipe*
+getpipe(ulong path)
+{
+ Pipe *p;
+
+ lock(&pipealloc);
+ for(p = pipealloc.pipe; p; p = p->next) {
+ if(path == p->path) {
+ unlock(&pipealloc);
+ return p;
+ }
+ }
+ unlock(&pipealloc);
+ panic("getpipe");
+ return 0;
+}
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/portdat.h => port/portdat.h +6 -8
@@ 41,11 41,6 @@ typedef int Devgen(Chan*, Dirtab*, int, int, Dir*);
#include "fcall.h"
-struct List
-{
- void *next;
-};
-
struct Ref
{
Lock;
@@ 108,7 103,8 @@ struct Block
ulong pc; /* pc of caller */
};
-struct Blist {
+struct Blist
+{
Lock;
Block *first; /* first data block */
Block *last; /* last data block */
@@ 205,7 201,8 @@ struct Env
/*
* Ethernet packet buffers.
*/
-struct Etherpkt {
+struct Etherpkt
+{
uchar d[6];
uchar s[6];
uchar type[2];
@@ 639,7 636,8 @@ struct Stream
/*
* stream file qid's & high water mark
*/
-enum {
+enum
+{
Shighqid = STREAMQID(1,0) - 1,
Sdataqid = Shighqid,
Sctlqid = Sdataqid-1,
M port/portfns.h => port/portfns.h +1 -4
@@ 1,7 1,6 @@
void alarmkproc(void*);
Block* allocb(ulong);
int anyready(void);
-void append(List**, List*);
Image* attachimage(int, Chan*, ulong, ulong);
int blen(Block *);
int bround(Block *, int);
@@ 34,8 33,6 @@ void copypage(Page*, Page*);
int decref(Ref*);
int decrypt(void*, void*, int);
void delay(int);
-void delete(List**, List*, List*);
-void delete0(List**, List*);
Chan* devattach(int, char*);
Chan* devclone(Chan*, Chan*);
void devdir(Chan*, Qid, char*, long, char*, long, Dir*);
@@ 90,7 87,6 @@ long ibrk(ulong, int);
int incref(Ref*);
void initq(IOQ*);
void initseg(void);
-void insert(List**, List*, List*);
void invalidateu(void);
void isdir(Chan*);
int ispages(void*);
@@ 248,6 244,7 @@ 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);
M port/segment.c => port/segment.c +0 -2
@@ 27,7 27,6 @@ static QLock ireclaim;
void
initseg(void)
{
- Segment *s, *se;
Image *i, *ie;
imagealloc.free = xalloc(conf.nimage*sizeof(Image));
@@ 360,7 359,6 @@ ibrk(ulong addr, int seg)
s->top = newtop;
s->size = newsize;
-
qunlock(&s->lk);
return 0;
}
M ss/dat.h => ss/dat.h +0 -1
@@ 79,7 79,6 @@ struct Conf
int nsubfont; /* Gsubfont structs (devbit.c) */
int nurp; /* max urp conversations */
int nasync; /* number of async protocol modules */
- int npipe; /* number of pipes */
int copymode; /* 0 is copy on write, 1 is copy on reference */
ulong ipif; /* Ip protocol interfaces */
ulong ip; /* Ip conversations per interface */
M ss/main.c => ss/main.c +2 -2
@@ 222,7 222,6 @@ confinit(void)
conf.nsubfont = 10*mul;
conf.nurp = 32;
conf.nasync = 1;
- conf.npipe = conf.nstream/2;
conf.copymode = 0; /* copy on write */
conf.ipif = 8;
conf.ip = 64;
@@ 263,7 262,8 @@ lancesetup(Lance *lp)
/*
* Allocate area for lance init block and descriptor rings
*/
- pa = (ulong)ialloc(BY2PG, 1)&~KZERO; /* one whole page */
+ pa = (ulong)xspanalloc(BY2PG, BY2PG, 0);
+
/* map at LANCESEGM */
k = kmappa(pa, PTEMAINMEM|PTENOCACHE);
lp->lanceram = (ushort*)k->va;