From 56d6000950883bfd3f5cad269bd5180e69ea96c4 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 21 Jun 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-06-21 --- gnot/dat.h | 15 +-- gnot/devport.c | 61 ++++++--- gnot/fns.h | 8 +- gnot/main.c | 18 +-- port/alloc.c | 53 ++++++-- port/devbit.c | 329 ++++++++++++++++++++++++++---------------------- port/devlance.c | 14 +-- port/devpipe.c | 94 ++++++++------ port/page.c | 2 +- port/portdat.h | 14 +-- port/portfns.h | 5 +- port/segment.c | 2 - ss/dat.h | 1 - ss/main.c | 4 +- 14 files changed, 337 insertions(+), 283 deletions(-) diff --git a/gnot/dat.h b/gnot/dat.h index 37ae82f4db0cb99bb2bcf619ef2c748546293363..b6be40bb51311c1819436e550449f2ac0244a3bf 100644 --- a/gnot/dat.h +++ b/gnot/dat.h @@ -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 */ diff --git a/gnot/devport.c b/gnot/devport.c index 06cb435acc7c62f0a83b920dd32aa39291430470..b111c9b47a452b88fc911ac85f3a870b0708453c 100644 --- a/gnot/devport.c +++ b/gnot/devport.c @@ -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; - } diff --git a/gnot/fns.h b/gnot/fns.h index 89e68c97342a43cb5c573b3ed086ee46af91d5f9..6be65fc8885e87be9aa5c628fe54533740bff18f 100644 --- a/gnot/fns.h +++ b/gnot/fns.h @@ -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) diff --git a/gnot/main.c b/gnot/main.c index 41674033ef5dc4b9a7341c2b2eadea121cfd8982..5d0f7f0dae1b665f807d7dfc587d31dffd0c90c1 100644 --- a/gnot/main.c +++ b/gnot/main.c @@ -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); } diff --git a/port/alloc.c b/port/alloc.c index 3ec7243526da279fa64a38f47c7f778c8d805768..56b5b224d48bc3016f11f47a3aacee001d25f748 100644 --- a/port/alloc.c +++ b/port/alloc.c @@ -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) { diff --git a/port/devbit.c b/port/devbit.c index dc7edbb78813fa7f392a5b9427b57c86513001f7..fa0c9bd554c9823dd973214ae8d0b418c67dfa73 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -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; ildepth = -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 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]; ildepth >= 0) - bitfree(bp); - for(i=1,fp=&bit.subfont[1]; ibits = 0; - for(i=0,ffp=&bit.font[0]; ib = 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(; bpldepth); 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; iinfo = 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; iheight = 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; bpbase[-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) { diff --git a/port/devlance.c b/port/devlance.c index bf9ba55611221eb2b49144c2f993e3b7a7adcbd5..627174a8800f56f855d13f4f8341b2c793846ea8 100644 --- a/port/devlance.c +++ b/port/devlance.c @@ -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", diff --git a/port/devpipe.c b/port/devpipe.c index 67d55f655949f936ecc25ce83e27005d69fcde58..2bb9f71b772f4afd3efbc7a1f9691f486ce25bf1 100644 --- a/port/devpipe.c +++ b/port/devpipe.c @@ -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); } @@ -265,9 +263,6 @@ pipewrite(Chan *c, void *va, long n, ulong offset) return n; } -/* - * 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; +} diff --git a/port/page.c b/port/page.c index 489d3dfabeadb13eb07712ebfaaa851f058c08df..f2a240ee88926620f2afc947bee8fe6c1f82114b 100644 --- a/port/page.c +++ b/port/page.c @@ -21,7 +21,7 @@ pageinit(void) palloc.head = xalloc(np*sizeof(Page)); if(palloc.head == 0) panic("pageinit"); - +print("page: %lux %d %lux %d\n", palloc.p0, palloc.np0, palloc.p1, palloc.np1); p = palloc.head; while(palloc.np0 > 0) { p->prev = p-1; diff --git a/port/portdat.h b/port/portdat.h index 354a01549b6a4550bd1373bb6bfb7c5000cf1850..e6a3f4cccb215aadad9f93d58f750dc0cc331a70 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -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, diff --git a/port/portfns.h b/port/portfns.h index 82a07cb265ec36198055ef6e5a6288b5add2a728..668e93dfec09222b25e4e08bdf3dde611809914f 100644 --- a/port/portfns.h +++ b/port/portfns.h @@ -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); diff --git a/port/segment.c b/port/segment.c index 6d6fdfd0ac7c16374f6ff14b069ebd79962152e6..71d2b540a286b6282ec18ce06abb0d872568f778 100644 --- a/port/segment.c +++ b/port/segment.c @@ -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; } diff --git a/ss/dat.h b/ss/dat.h index 62d3396563de243d845d39e9945c42d3b9b7c9be..c2821c26ded6c712a426e1583025dbe39c3d5901 100644 --- a/ss/dat.h +++ b/ss/dat.h @@ -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 */ diff --git a/ss/main.c b/ss/main.c index c95dd8f4860873d0e053f142d000656159b7a01f..45152f076969eddaacc329a6adefb87f63df1907 100644 --- a/ss/main.c +++ b/ss/main.c @@ -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;