1 /* Inferno tree allocator */ 2 3 typedef struct Pool Pool; 4 typedef struct Bhdr Bhdr; 5 typedef struct Btail Btail; 6 7 #pragma incomplete Pool 8 9 enum 10 { 11 MAGIC_A = 0xa110c, /* Allocated block */ 12 MAGIC_F = 0xbadc0c0a, /* Free block */ 13 MAGIC_E = 0xdeadbabe, /* End of arena */ 14 MAGIC_I = 0xabba /* Block is immutable (hidden from gc) */ 15 }; 16 17 struct Bhdr 18 { 19 ulong magic; 20 ulong size; 21 union { 22 uchar data[1]; 23 struct { 24 Bhdr* bhl; 25 Bhdr* bhr; 26 Bhdr* bhp; 27 Bhdr* bhv; 28 Bhdr* bhf; 29 } s; 30 #define clink u.l.link 31 #define csize u.l.size 32 struct { 33 Bhdr* link; 34 int size; 35 } l; 36 } u; 37 }; 38 39 struct Btail 40 { 41 /* ulong pad; */ 42 Bhdr* hdr; 43 }; 44 45 #define B2D(bp) ((void*)bp->u.data) 46 #define D2B(b, dp) b = ((Bhdr*)(((uchar*)dp)-(((Bhdr*)0)->u.data))); \ 47 if(b->magic != MAGIC_A && b->magic != MAGIC_I)\ 48 poolfault(dp, "alloc:D2B", getcallerpc(&dp)); 49 #define B2NB(b) ((Bhdr*)((uchar*)b + b->size)) 50 #define B2PT(b) ((Btail*)((uchar*)b - sizeof(Btail))) 51 #define B2T(b) ((Btail*)(((uchar*)b)+b->size-sizeof(Btail))) 52 53 #define B2LIMIT(b) ((Bhdr*)((uchar*)b + b->csize)) 54 55 #define BHDRSIZE ((int)(((Bhdr*)0)->u.data)+sizeof(Btail)) 56 57 extern void (*poolfault)(void *, char *, ulong); 58 extern void poolinit(void); 59 extern void* poolalloc(Pool*, ulong); 60 extern void poolfree(Pool*, void*); 61 extern Bhdr* poolchain(Pool*); 62 extern int poolcompact(Pool*); 63 extern void poolimmutable(void*); 64 extern ulong poolmsize(Pool*, void*); 65 extern void poolmutable(void*); 66 extern char* poolname(Pool*); 67 extern int poolread(char*, int, ulong); 68 extern void* poolrealloc(Pool*, void*, ulong); 69 extern int poolsetsize(char*, int); 70 extern void poolsetcompact(Pool*, void (*)(void*, void*)); 71 extern char* poolaudit(char*(*)(int, Bhdr *)); 72 73 extern void (*poolmonitor)(int, ulong, Bhdr*, ulong); 74