~kris/9p

9hist

742b4de03522c78319e649a34064c87af3b78d49 — David du Colombier 34 years ago 7e7a0ef
Plan 9 from Bell Labs 1992-06-18
4 files changed, 175 insertions(+), 23 deletions(-)

A port/alloc.c
M port/malloc.c
M port/page.c
M power/devcyc.c
A port/alloc.c => port/alloc.c +150 -0
@@ 0,0 1,150 @@
#include	"u.h"
#include	"../port/lib.h"
#include	"mem.h"
#include	"dat.h"
#include	"fns.h"
#define	nil	((void*)0)
#define datoff	((int)&((Xhdr*)0)->data)

enum
{
	Nhole	= 128,
	Magic	= 0xDeadBabe,
};

typedef struct Hole Hole;
typedef struct Xalloc Xalloc;
typedef struct Xhdr Xhdr;
struct Hole
{
	ulong	addr;
	ulong	size;
	ulong	top;
	Hole	*link;
};

struct Xhdr
{
	ulong	size;
	ulong	magix;
	char	data[1];
};

struct Xalloc
{
	Lock;
	Hole	hole[Nhole];
	Hole	*flist;
	Hole	*table;
};

Xalloc	xlists;

void
xinit(void)
{
	Hole *h, *eh;

	eh = &xlists.hole[Nhole-1];
	for(h = xlists.hole; h < eh; h++)
		h->link = h+1;

	xlists.flist = h;
}

void
xhole(ulong addr, ulong size)
{
	Hole *h, **l;

	lock(&xlists);
	l = &xlists.table;
	for(h = *l; h; h = h->link) {
		if(h->top == addr) {
			h->size += size;
			h->top = h->addr+h->size;
			unlock(&xlists);
			return;
		}
		if(h->addr > addr)
			break;
		l = &h->link;
	}

	if(xlists.flist == nil) {
		print("xfree: no free holes, leaked %d bytes\n", size);
		unlock(&xlists);
		return;
	}

	h = xlists.flist;
	xlists.flist = h->link;
	h->addr = addr;
	h->top = addr+size;
	h->size = size;
	h->link = *l;
	*l = h;
	unlock(&xlists);
}

void*
xalloc(ulong size)
{
	Hole *h, **l;
	Xhdr *p;

	size += sizeof(Xhdr);

	lock(&xlists);
	l = &xlists.table;
	for(h = *l; h; h = h->link) {
		if(h->size >= size) {
			p = (Xhdr*)h->addr;
			h->addr += size;
			h->size -= size;
			if(h->size == 0) {
				*l = h->link;
				h->link = xlists.flist;
				xlists.flist = h;
			}
			p->magix = Magic;
			p->size = size;
			unlock(&xlists);
			return p->data;
		}
		l = &h->link;
	}
	unlock(&xlists);
	return nil;
}

void
xfree(void *p)
{
	Xhdr *x;

	x = (Xhdr*)((ulong)p - datoff);
	if(x->magix != Magic)
		panic("xfree");

	xhole((ulong)x, x->size);
}

void
xsummary(void)
{
	int i;
	Hole *h;

	i = 0;
	for(h = xlists.flist; h; h = h->link)
		i++;

	print("%d holes free\n", i);
	i = 0;
	for(h = xlists.table; h; h = h->link) {
		print("%lux %lux %d\n", h->addr, h->top, h->size);
		i += h->size;
	}
	print("%d bytes free\n", i);
}

M port/malloc.c => port/malloc.c +11 -12
@@ 4,7 4,7 @@
enum
{
	MAGIC		= 0xDEADBABE,
	MAX2SIZE	= 20
	MAXPOW		= 20
};

typedef struct Bucket Bucket;


@@ 20,9 20,8 @@ typedef struct Arena Arena;
struct Arena
{
	Lock;
	Bucket	*btab[MAX2SIZE];	
	Bucket	*btab[MAXPOW];
};

static Arena arena;
#define datoff		((int)&((Bucket*)0)->data)



@@ 32,14 31,15 @@ malloc(uint size)
	int pow;
	Bucket *bp;

	for(pow = 1; pow < MAX2SIZE; pow++) {
	size += sizeof(Bucket);

	for(pow = 1; pow < MAXPOW; pow++)
		if(size <= (1<<pow))
			goto good;
	}

	return nil;
	return 0;

good:
	/* Allocate off this list */
	lock(&arena);
	bp = arena.btab[pow];
	if(bp) {


@@ 47,7 47,7 @@ good:
		arena.unlock();

		if(bp->magic != 0)
			abort();
			panic("malloc");

		bp->magic = MAGIC;



@@ 55,14 55,13 @@ good:
		return  bp->data;
	}
	unlock(&arena);

	size = sizeof(Bucket)+(1<<pow);
	bp = sbrk(size);
	bp = xbrk(size);
	if((int)bp < 0)
		return nil;

	bp->size = pow;
	bp->magic = MAGIC;

	memset(bp->data, 0,  size);
	return bp->data;
}


M port/page.c => port/page.c +14 -10
@@ 66,11 66,14 @@ Region region[Nregion];
void
addsplit(Region *r, ulong start, ulong end)
{
	Region *rr;
	int len = end - start;
	int len;
	Region *rr, *eregion;

	len = end - start;
	eregion = &region[Nregion];

	/* first look for an unused one */
	for(rr = region; rr < &region[Nregion]; rr++){
	for(rr = region; rr < eregion; rr++){
		if(rr == r)
			continue;
		if(rr->end - rr->start == 0){


@@ 81,7 84,7 @@ addsplit(Region *r, ulong start, ulong end)
	}

	/* then look for a smaller one */
	for(rr = region; rr < &region[Nregion]; rr++){
	for(rr = region; rr < eregion; rr++){
		if(rr == r)
			continue;
		if(rr->end - rr->start < len){


@@ 105,19 108,21 @@ addsplit(Region *r, ulong start, ulong end)
void*
iallocspan(ulong n, int align, ulong crevasse)
{
	int m;
	ulong p;
	Region *r;
	int m;
	int ledge;

	if(palloc.active && n!=0)
		print("ialloc bad\n");

	if(palloc.addr0 == 0){
		region[Nregion-2].start = (((ulong)end)&~KZERO) + conf.base0;
		region[Nregion-2].end = conf.base0 + (conf.npage0<<PGSHIFT);
		region[Nregion-1].start = conf.base1;
		region[Nregion-1].end = conf.base1 + (conf.npage1<<PGSHIFT);
		r = &region[Nregion-2];
		r->start = (((ulong)end)&~KZERO) + conf.base0;
		r->end = conf.base0 + (conf.npage0<<PGSHIFT);
		r++;
		r->start = conf.base1;
		r->end = conf.base1 + (conf.npage1<<PGSHIFT);

		palloc.addr0 = region[Nregion-2].start;
		palloc.addr1 = region[Nregion-1].start;


@@ 174,7 179,6 @@ iallocspan(ulong n, int align, ulong crevasse)
	 *  zero it
	 */
	memset((void*)(p|KZERO), 0, n);

	return (void*)(p|KZERO);
}


M power/devcyc.c => power/devcyc.c +0 -1
@@ 204,7 204,6 @@ cycclose(Chan *c)
	}
}


int
cycmsgintr(Cycmsg *hm)
{