87 lines · 2.1 KB · C
RawDownload
/* Inferno tree allocator */ typedef struct Pool Pool;typedef struct Bhdr Bhdr;typedef struct Btail Btail;typedef struct Balign Balign; #pragma incomplete Pool enum{	MAGIC_A		= 0xa110c,		/* Allocated block */	MAGIC_F		= 0xbadc0c0a,		/* Free block */	MAGIC_E		= 0xdeadbabe,		/* End of arena */	MAGIC_I		= 0xabba		/* Block is immutable (hidden from gc) */	/* MAGIC_ALIGNED	= 0xa1f1d1c */	/* Block header for the aligned pointer */}; struct Bhdr{	u32	magic;	uintptr	size;	intptr	allocpc;	intptr	reallocpc;	union {		uchar data[1];		struct {			Bhdr*	bhl;			Bhdr*	bhr;			Bhdr*	bhp;			Bhdr*	bhv;			Bhdr*	bhf;		} s;#define clink	u.l.link#define csize	u.l.size		struct {			Bhdr*	link;			intptr	size;		} l;	} u;}; struct Btail{	/* ulong	pad; */	Bhdr*	hdr;}; struct Balign{	/* u32	magic; */	Bhdr*	hdr;}; #define B2D(bp)		((void*)bp->u.data)#define D2B(b, dp)	b = ((Bhdr*)(((uchar*)dp)-(((Bhdr*)0)->u.data))); \			if(b->magic != MAGIC_A && b->magic != MAGIC_I){\				b = ((Balign*)((char*)dp-sizeof(Balign)))->hdr; \				if(b->magic != MAGIC_A && b->magic != MAGIC_I)\					poolfault(dp, "alloc:D2B", getcallerpc(&dp));\			}#define B2NB(b)		((Bhdr*)((uchar*)b + b->size))#define B2PT(b)		((Btail*)((uchar*)b - sizeof(Btail)))#define B2T(b)		((Btail*)(((uchar*)b)+b->size-sizeof(Btail))) #define B2LIMIT(b)	((Bhdr*)((uchar*)b + b->csize)) #define BHDRSIZE	((uintptr)(((Bhdr*)0)->u.data)+sizeof(Btail)) extern	void	(*poolfault)(void *, char *, uintptr);extern	void	poolinit(void);extern	void*	poolalloc(Pool*, uintptr);extern	void	poolfree(Pool*, void*);extern	Bhdr*	poolchain(Pool*);extern	int	poolcompact(Pool*);extern	void	poolimmutable(void*);extern	uintptr	poolmsize(Pool*, void*);extern	void	poolmutable(void*);extern	char*	poolname(Pool*);extern	int	poolread(char*, int, uintptr);extern	void*	poolrealloc(Pool*, void*, uintptr);extern	int	poolsetsize(char*, int);extern	void	poolsetcompact(Pool*, void (*)(void*, void*));extern	char*	poolaudit(char*(*)(int, Bhdr *)); extern	void	(*poolmonitor)(int, ulong, Bhdr*, ulong);extern	void	showframe(void *f, void *t);