~kris/9p

9hist

0669755933d2f90a9b3dacd16055e20ca73c84fa — David du Colombier 34 years ago 34ff23b
Plan 9 from Bell Labs 1992-07-06
1 files changed, 105 insertions(+), 49 deletions(-)

M port/devbit.c
M port/devbit.c => port/devbit.c +105 -49
@@ 173,6 173,36 @@ Dirtab bitdir[]={
#define	HDR	3

void
bitfreeup(void)
{
	int i;
	BSubfont *s;

	/* free unused subfonts and compact */
	for(i=0; i<bit.nsubfont; i++){
		s = bit.subfont[i];
		if(s && s!=defont && s->ref==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)
{
	int i;


@@ 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; i<bit.nsubfont; i++)
				if(bit.subfont[i] == 0)
					goto subfontfound;
			fp = bit.subfont;
			bit.subfont = smalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
			memmove(bit.subfont, fp, bit.nsubfont*sizeof(BSubfont*));
			free(fp);
			fp = bitmalloc((bit.nsubfont+DMAP)*sizeof(BSubfont*));
			if(fp == 0)
				error(Enomem);
			memmove(fp, bit.subfont, bit.nsubfont*sizeof(BSubfont*));
			free(bit.subfont);
			bit.subfont = fp;
			bit.nsubfont += DMAP;
		subfontfound:
			f = smalloc(sizeof(BSubfont));
			f = bitmalloc(sizeof(BSubfont));
			if(f == 0)
				error(Enomem);
			bit.subfont[i] = f;
			f->info = 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; i<bit.nfont; i++)
				if(bit.font[i] == 0)
					goto fontfound;
			ffp = bit.font;
			bit.font = smalloc((bit.nfont+DMAP)*sizeof(GFont*));
			memmove(bit.font, ffp, bit.nfont*sizeof(GFont*));
			free(ffp);
			ffp = bitmalloc((bit.nfont+DMAP)*sizeof(GFont*));
			if(ffp == 0)
				error(Enomem);
			memmove(ffp, bit.font, bit.nfont*sizeof(GFont*));
			free(bit.font);
			bit.font = ffp;
			bit.nfont += DMAP;
		fontfound:
			ff = smalloc(sizeof(GFont));
			ff = bitmalloc(sizeof(GFont));
			if(ff == 0)
				error(Enomem);
			ff->ncache = 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; i<bit.nsubfont; i++){
		s = bit.subfont[i];
		if(s && s!=defont && s->ref==0){
			s->ref = 1;
			s->qid[0] = ~0;	/* force cleanup */
			subfontfree(s, i);
		}
	}
	bitcompact();
	bitfreeup();

	for(a=bit.arena; a<ea; a++){
		if(a->words == 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 || a>=bit.arena+bit.narena) panic("bitfree");
		a->nbusy--;
		if(a->nbusy == 0)
			arenafree(a);