From 0669755933d2f90a9b3dacd16055e20ca73c84fa Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 6 Jul 1992 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 1992-07-06 --- port/devbit.c | 154 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 49 deletions(-) diff --git a/port/devbit.c b/port/devbit.c index 94ec62b7e8b497d39e070dd0e1215d5296a7e431..9fe0347078ade284d59e4fdcf15b5268058ea03b 100644 --- a/port/devbit.c +++ b/port/devbit.c @@ -172,6 +172,36 @@ Dirtab bitdir[]={ #define NINFO 8192 /* max chars per subfont; sanity check only */ #define HDR 3 +void +bitfreeup(void) +{ + int i; + BSubfont *s; + + /* free unused subfonts and compact */ + for(i=0; iref==0){ + s->ref = 1; + s->qid[0] = ~0; /* force cleanup */ + subfontfree(s, i); + } + } + bitcompact(); +} + +void* +bitmalloc(ulong n) +{ + void *p; + + p = malloc(n); + if(p) + return p; + bitfreeup(); + return malloc(n); +} + void bitdebug(void) { @@ -212,7 +242,7 @@ bitdebug(void) void bitreset(void) { - int i; + int i, ws; GBitmap *bp; ulong r; Arena *a; @@ -237,10 +267,17 @@ bitreset(void) * 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); + ws = BI2WD>>gscreen.ldepth; /* pixels per word */ + a->nwords = 3*(HDR + gscreen.r.max.y*gscreen.r.max.x/ws); a->words = xalloc(a->nwords*sizeof(ulong)); - if(a->words == 0) - panic("bitreset"); + if(a->words == 0){ + /* try again */ + print("bitreset: allocating only 1 screenful\n"); + a->nwords /= 3; + a->words = 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); @@ -674,6 +711,7 @@ bitwrite(Chan *c, void *va, long n, ulong offset) GBitmap *b, *src, *dst, *bp; BSubfont *f, *tf, **fp; GFont *ff, **ffp; + GCacheinfo *gc; if(c->qid.path == CHDIR) error(Eisdir); @@ -909,15 +947,23 @@ bitwrite(Chan *c, void *va, long n, ulong offset) for(i=1; iinfo = smalloc((v+1)*sizeof(Fontchar)); + f->info = bitmalloc((v+1)*sizeof(Fontchar)); + if(f->info == 0){ + free(f); + error(Enomem); + } f->n = v; f->height = p[3]; f->ascent = p[4]; @@ -1028,15 +1074,23 @@ bitwrite(Chan *c, void *va, long n, ulong offset) for(i=0; incache = t; - ff->cache = smalloc(t*sizeof(GCacheinfo)); + ff->cache = bitmalloc(t*sizeof(GCacheinfo)); + if(ff->cache == 0){ + free(ff); + error(Enomem); + } bit.font[i] = ff; ff = bit.font[i]; ff->height = p[1]; @@ -1227,24 +1281,29 @@ bitwrite(Chan *c, void *va, long n, ulong offset) error(Ebadblt); x = BGSHORT(p+5); i = bitalloc(Rect(0, 0, t*x, ff->height), ff->ldepth); - /* now committed */ + if(t != ff->ncache){ + gc = bitmalloc(t*sizeof(ff->cache[0])); + if(gc == 0){ + bitfree(bit.map[i]); + bit.map[i] = 0; + error(Enomem); + } + free(ff->cache); + ff->cache = gc; + ff->ncache = t; + }else{ + /* + * memset not necessary but helps avoid + * confusion if the cache is mishandled by the + * user. + */ + memset(ff->cache, 0, t*sizeof(ff->cache[0])); + } if(ff->b) bitfree(ff->b); ff->b = bit.map[i]; bit.map[i] = 0; /* disconnect it from GBitmap space */ ff->width = x; - /* - * memset not necessary but helps avoid - * confusion if the cache is mishandled by the - * user. - */ - if(t == ff->ncache) - memset(ff->cache, 0, t*sizeof(ff->cache[0])); - else{ - free(ff->cache); - ff->cache = smalloc(t*sizeof(ff->cache[0])); - ff->ncache = t; - } p += 7; m -= 7; break; @@ -1398,7 +1457,7 @@ bitalloc(Rectangle rect, int ld) long t; int i, try; - ws = 1<<(5-ld); /* pixels per word */ + ws = BI2WD>>ld; /* pixels per word */ if(rect.min.x >= 0){ l = (rect.max.x+ws-1)/ws; l -= rect.min.x/ws; @@ -1434,7 +1493,7 @@ bitalloc(Rectangle rect, int ld) /* need new arena */ if(aa){ a = aa; - a->nwords = gscreen.width*gscreen.r.max.y+HDR; + a->nwords = HDR + (gscreen.r.max.y*gscreen.r.max.x)/ws; if(a->nwords < HDR+nw) a->nwords = HDR+nw; a->words = xalloc(a->nwords*sizeof(ulong)); @@ -1446,16 +1505,8 @@ bitalloc(Rectangle rect, int ld) } /* else can't grow list: bitmaps have backpointers */ - /* free unused subfonts, compact, and try again */ - for(i=0; iref==0){ - s->ref = 1; - s->qid[0] = ~0; /* force cleanup */ - subfontfree(s, i); - } - } - bitcompact(); + bitfreeup(); + for(a=bit.arena; awords == 0) continue; @@ -1466,11 +1517,13 @@ bitalloc(Rectangle rect, int ld) error(Enobitstore); found: - b = smalloc(sizeof(GBitmap)); + b = bitmalloc(sizeof(GBitmap)); + if(b == 0) + error(Enomem); *a->wfree++ = nw; *a->wfree++ = (ulong)a; *a->wfree++ = (ulong)b; - memset(a->wfree, 0, (nw-HDR)*sizeof(ulong)); + memset(a->wfree, 0, nw*sizeof(ulong)); b->base = a->wfree; a->wfree += nw; a->nbusy++; @@ -1491,11 +1544,15 @@ bitalloc(Rectangle rect, int ld) 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; + bp = bitmalloc((bit.nmap+DMAP)*sizeof(GBitmap*)); + if(bp == 0){ + bitfree(b); + error(Enomem); + } + memmove(bp, bit.map, bit.nmap*sizeof(GBitmap*)); + free(bit.map); + bit.map = bp; + bp += bit.nmap; bit.nmap += DMAP; } *bp = b; @@ -1509,7 +1566,6 @@ bitfree(GBitmap *b) if(b->base != gscreen.base){ /* can't free screen memory */ a = (Arena*)(b->base[-2]); -if(a=bit.arena+bit.narena) panic("bitfree"); a->nbusy--; if(a->nbusy == 0) arenafree(a);