1*3e12c5d1SDavid du Colombier #include <u.h> 2*3e12c5d1SDavid du Colombier #include <libc.h> 3*3e12c5d1SDavid du Colombier 4*3e12c5d1SDavid du Colombier enum 5*3e12c5d1SDavid du Colombier { 6*3e12c5d1SDavid du Colombier MAGIC = 0xbada110c, 7*3e12c5d1SDavid du Colombier MAX2SIZE = 32, 8*3e12c5d1SDavid du Colombier CUTOFF = 12, 9*3e12c5d1SDavid du Colombier }; 10*3e12c5d1SDavid du Colombier 11*3e12c5d1SDavid du Colombier typedef struct Bucket Bucket; 12*3e12c5d1SDavid du Colombier struct Bucket 13*3e12c5d1SDavid du Colombier { 14*3e12c5d1SDavid du Colombier int size; 15*3e12c5d1SDavid du Colombier int magic; 16*3e12c5d1SDavid du Colombier Bucket *next; 17*3e12c5d1SDavid du Colombier char data[1]; 18*3e12c5d1SDavid du Colombier }; 19*3e12c5d1SDavid du Colombier 20*3e12c5d1SDavid du Colombier typedef struct Arena Arena; 21*3e12c5d1SDavid du Colombier struct Arena 22*3e12c5d1SDavid du Colombier { 23*3e12c5d1SDavid du Colombier Bucket *btab[MAX2SIZE]; 24*3e12c5d1SDavid du Colombier }; 25*3e12c5d1SDavid du Colombier static Arena arena; 26*3e12c5d1SDavid du Colombier 27*3e12c5d1SDavid du Colombier #define datoff ((int)((Bucket*)0)->data) 28*3e12c5d1SDavid du Colombier #define nil ((void*)0) 29*3e12c5d1SDavid du Colombier 30*3e12c5d1SDavid du Colombier void* 31*3e12c5d1SDavid du Colombier malloc(long size) 32*3e12c5d1SDavid du Colombier { 33*3e12c5d1SDavid du Colombier ulong next; 34*3e12c5d1SDavid du Colombier int pow, n; 35*3e12c5d1SDavid du Colombier Bucket *bp, *nbp; 36*3e12c5d1SDavid du Colombier 37*3e12c5d1SDavid du Colombier for(pow = 1; pow < MAX2SIZE; pow++) { 38*3e12c5d1SDavid du Colombier if(size <= (1<<pow)) 39*3e12c5d1SDavid du Colombier goto good; 40*3e12c5d1SDavid du Colombier } 41*3e12c5d1SDavid du Colombier 42*3e12c5d1SDavid du Colombier return nil; 43*3e12c5d1SDavid du Colombier good: 44*3e12c5d1SDavid du Colombier /* Allocate off this list */ 45*3e12c5d1SDavid du Colombier bp = arena.btab[pow]; 46*3e12c5d1SDavid du Colombier if(bp) { 47*3e12c5d1SDavid du Colombier arena.btab[pow] = bp->next; 48*3e12c5d1SDavid du Colombier 49*3e12c5d1SDavid du Colombier if(bp->magic != 0) 50*3e12c5d1SDavid du Colombier abort(); 51*3e12c5d1SDavid du Colombier 52*3e12c5d1SDavid du Colombier bp->magic = MAGIC; 53*3e12c5d1SDavid du Colombier return bp->data; 54*3e12c5d1SDavid du Colombier } 55*3e12c5d1SDavid du Colombier size = sizeof(Bucket)+(1<<pow); 56*3e12c5d1SDavid du Colombier size += 3; 57*3e12c5d1SDavid du Colombier size &= ~3; 58*3e12c5d1SDavid du Colombier 59*3e12c5d1SDavid du Colombier if(pow < CUTOFF) { 60*3e12c5d1SDavid du Colombier n = (CUTOFF-pow)+2; 61*3e12c5d1SDavid du Colombier bp = sbrk(size*n); 62*3e12c5d1SDavid du Colombier if((int)bp < 0) 63*3e12c5d1SDavid du Colombier return nil; 64*3e12c5d1SDavid du Colombier 65*3e12c5d1SDavid du Colombier next = (ulong)bp+size; 66*3e12c5d1SDavid du Colombier nbp = (Bucket*)next; 67*3e12c5d1SDavid du Colombier arena.btab[pow] = nbp; 68*3e12c5d1SDavid du Colombier for(n -= 2; n; n--) { 69*3e12c5d1SDavid du Colombier next = (ulong)nbp+size; 70*3e12c5d1SDavid du Colombier nbp->next = (Bucket*)next; 71*3e12c5d1SDavid du Colombier nbp->size = pow; 72*3e12c5d1SDavid du Colombier nbp = nbp->next; 73*3e12c5d1SDavid du Colombier } 74*3e12c5d1SDavid du Colombier nbp->size = pow; 75*3e12c5d1SDavid du Colombier } 76*3e12c5d1SDavid du Colombier else { 77*3e12c5d1SDavid du Colombier bp = sbrk(size); 78*3e12c5d1SDavid du Colombier if((int)bp < 0) 79*3e12c5d1SDavid du Colombier return nil; 80*3e12c5d1SDavid du Colombier } 81*3e12c5d1SDavid du Colombier 82*3e12c5d1SDavid du Colombier bp->size = pow; 83*3e12c5d1SDavid du Colombier bp->magic = MAGIC; 84*3e12c5d1SDavid du Colombier 85*3e12c5d1SDavid du Colombier return bp->data; 86*3e12c5d1SDavid du Colombier } 87*3e12c5d1SDavid du Colombier 88*3e12c5d1SDavid du Colombier void* 89*3e12c5d1SDavid du Colombier calloc(long n, long size) 90*3e12c5d1SDavid du Colombier { 91*3e12c5d1SDavid du Colombier void *p; 92*3e12c5d1SDavid du Colombier 93*3e12c5d1SDavid du Colombier n *= size; 94*3e12c5d1SDavid du Colombier p = malloc(n); 95*3e12c5d1SDavid du Colombier if(p) 96*3e12c5d1SDavid du Colombier memset(p, 0, n); 97*3e12c5d1SDavid du Colombier 98*3e12c5d1SDavid du Colombier return p; 99*3e12c5d1SDavid du Colombier } 100*3e12c5d1SDavid du Colombier 101*3e12c5d1SDavid du Colombier void 102*3e12c5d1SDavid du Colombier free(void *ptr) 103*3e12c5d1SDavid du Colombier { 104*3e12c5d1SDavid du Colombier Bucket *bp, **l; 105*3e12c5d1SDavid du Colombier 106*3e12c5d1SDavid du Colombier if(ptr == nil) 107*3e12c5d1SDavid du Colombier return; 108*3e12c5d1SDavid du Colombier 109*3e12c5d1SDavid du Colombier /* Find the start of the structure */ 110*3e12c5d1SDavid du Colombier bp = (Bucket*)((uint)ptr - datoff); 111*3e12c5d1SDavid du Colombier 112*3e12c5d1SDavid du Colombier if(bp->magic != MAGIC) 113*3e12c5d1SDavid du Colombier abort(); 114*3e12c5d1SDavid du Colombier 115*3e12c5d1SDavid du Colombier bp->magic = 0; 116*3e12c5d1SDavid du Colombier l = &arena.btab[bp->size]; 117*3e12c5d1SDavid du Colombier bp->next = *l; 118*3e12c5d1SDavid du Colombier *l = bp; 119*3e12c5d1SDavid du Colombier } 120*3e12c5d1SDavid du Colombier 121*3e12c5d1SDavid du Colombier void* 122*3e12c5d1SDavid du Colombier realloc(void *ptr, long n) 123*3e12c5d1SDavid du Colombier { 124*3e12c5d1SDavid du Colombier void *new; 125*3e12c5d1SDavid du Colombier uint osize; 126*3e12c5d1SDavid du Colombier Bucket *bp; 127*3e12c5d1SDavid du Colombier 128*3e12c5d1SDavid du Colombier if(ptr == nil) 129*3e12c5d1SDavid du Colombier return malloc(n); 130*3e12c5d1SDavid du Colombier 131*3e12c5d1SDavid du Colombier /* Find the start of the structure */ 132*3e12c5d1SDavid du Colombier bp = (Bucket*)((uint)ptr - datoff); 133*3e12c5d1SDavid du Colombier 134*3e12c5d1SDavid du Colombier if(bp->magic != MAGIC) 135*3e12c5d1SDavid du Colombier abort(); 136*3e12c5d1SDavid du Colombier 137*3e12c5d1SDavid du Colombier /* enough space in this bucket */ 138*3e12c5d1SDavid du Colombier osize = 1<<bp->size; 139*3e12c5d1SDavid du Colombier if(osize >= n) 140*3e12c5d1SDavid du Colombier return ptr; 141*3e12c5d1SDavid du Colombier 142*3e12c5d1SDavid du Colombier new = malloc(n); 143*3e12c5d1SDavid du Colombier if(new == nil) 144*3e12c5d1SDavid du Colombier return nil; 145*3e12c5d1SDavid du Colombier 146*3e12c5d1SDavid du Colombier memmove(new, ptr, osize); 147*3e12c5d1SDavid du Colombier free(ptr); 148*3e12c5d1SDavid du Colombier 149*3e12c5d1SDavid du Colombier return new; 150*3e12c5d1SDavid du Colombier } 151