13e12c5d1SDavid du Colombier #include <stdlib.h> 23e12c5d1SDavid du Colombier #include <string.h> 33e12c5d1SDavid du Colombier 43e12c5d1SDavid du Colombier typedef unsigned int uint; 53e12c5d1SDavid du Colombier 63e12c5d1SDavid du Colombier enum 73e12c5d1SDavid du Colombier { 83e12c5d1SDavid du Colombier MAGIC = 0xbada110c, 93e12c5d1SDavid du Colombier MAX2SIZE = 32, 103e12c5d1SDavid du Colombier CUTOFF = 12, 113e12c5d1SDavid du Colombier }; 123e12c5d1SDavid du Colombier 133e12c5d1SDavid du Colombier typedef struct Bucket Bucket; 143e12c5d1SDavid du Colombier struct Bucket 153e12c5d1SDavid du Colombier { 163e12c5d1SDavid du Colombier int size; 173e12c5d1SDavid du Colombier int magic; 183e12c5d1SDavid du Colombier Bucket *next; 19*219b2ee8SDavid du Colombier int pad; 203e12c5d1SDavid du Colombier char data[1]; 213e12c5d1SDavid du Colombier }; 223e12c5d1SDavid du Colombier 233e12c5d1SDavid du Colombier typedef struct Arena Arena; 243e12c5d1SDavid du Colombier struct Arena 253e12c5d1SDavid du Colombier { 263e12c5d1SDavid du Colombier Bucket *btab[MAX2SIZE]; 273e12c5d1SDavid du Colombier }; 283e12c5d1SDavid du Colombier static Arena arena; 293e12c5d1SDavid du Colombier 303e12c5d1SDavid du Colombier #define datoff ((int)((Bucket*)0)->data) 313e12c5d1SDavid du Colombier #define nil ((void*)0) 323e12c5d1SDavid du Colombier 333e12c5d1SDavid du Colombier extern void *sbrk(unsigned long); 343e12c5d1SDavid du Colombier 353e12c5d1SDavid du Colombier void* 363e12c5d1SDavid du Colombier malloc(size_t size) 373e12c5d1SDavid du Colombier { 383e12c5d1SDavid du Colombier uint next; 393e12c5d1SDavid du Colombier int pow, n; 403e12c5d1SDavid du Colombier Bucket *bp, *nbp; 413e12c5d1SDavid du Colombier 423e12c5d1SDavid du Colombier for(pow = 1; pow < MAX2SIZE; pow++) { 433e12c5d1SDavid du Colombier if(size <= (1<<pow)) 443e12c5d1SDavid du Colombier goto good; 453e12c5d1SDavid du Colombier } 463e12c5d1SDavid du Colombier 473e12c5d1SDavid du Colombier return nil; 483e12c5d1SDavid du Colombier good: 493e12c5d1SDavid du Colombier /* Allocate off this list */ 503e12c5d1SDavid du Colombier bp = arena.btab[pow]; 513e12c5d1SDavid du Colombier if(bp) { 523e12c5d1SDavid du Colombier arena.btab[pow] = bp->next; 533e12c5d1SDavid du Colombier 543e12c5d1SDavid du Colombier if(bp->magic != 0) 553e12c5d1SDavid du Colombier abort(); 563e12c5d1SDavid du Colombier 573e12c5d1SDavid du Colombier bp->magic = MAGIC; 583e12c5d1SDavid du Colombier return bp->data; 593e12c5d1SDavid du Colombier } 603e12c5d1SDavid du Colombier size = sizeof(Bucket)+(1<<pow); 61*219b2ee8SDavid du Colombier size += 7; 62*219b2ee8SDavid du Colombier size &= ~7; 633e12c5d1SDavid du Colombier 643e12c5d1SDavid du Colombier if(pow < CUTOFF) { 653e12c5d1SDavid du Colombier n = (CUTOFF-pow)+2; 663e12c5d1SDavid du Colombier bp = sbrk(size*n); 673e12c5d1SDavid du Colombier if((int)bp < 0) 683e12c5d1SDavid du Colombier return nil; 693e12c5d1SDavid du Colombier 703e12c5d1SDavid du Colombier next = (uint)bp+size; 713e12c5d1SDavid du Colombier nbp = (Bucket*)next; 723e12c5d1SDavid du Colombier arena.btab[pow] = nbp; 733e12c5d1SDavid du Colombier for(n -= 2; n; n--) { 743e12c5d1SDavid du Colombier next = (uint)nbp+size; 753e12c5d1SDavid du Colombier nbp->next = (Bucket*)next; 763e12c5d1SDavid du Colombier nbp->size = pow; 773e12c5d1SDavid du Colombier nbp = nbp->next; 783e12c5d1SDavid du Colombier } 793e12c5d1SDavid du Colombier nbp->size = pow; 803e12c5d1SDavid du Colombier } 813e12c5d1SDavid du Colombier else { 823e12c5d1SDavid du Colombier bp = sbrk(size); 833e12c5d1SDavid du Colombier if((int)bp < 0) 843e12c5d1SDavid du Colombier return nil; 853e12c5d1SDavid du Colombier } 863e12c5d1SDavid du Colombier 873e12c5d1SDavid du Colombier bp->size = pow; 883e12c5d1SDavid du Colombier bp->magic = MAGIC; 893e12c5d1SDavid du Colombier 903e12c5d1SDavid du Colombier return bp->data; 913e12c5d1SDavid du Colombier } 923e12c5d1SDavid du Colombier 933e12c5d1SDavid du Colombier void 943e12c5d1SDavid du Colombier free(void *ptr) 953e12c5d1SDavid du Colombier { 963e12c5d1SDavid du Colombier Bucket *bp, **l; 973e12c5d1SDavid du Colombier 983e12c5d1SDavid du Colombier if(ptr == nil) 993e12c5d1SDavid du Colombier return; 1003e12c5d1SDavid du Colombier 1013e12c5d1SDavid du Colombier /* Find the start of the structure */ 1023e12c5d1SDavid du Colombier bp = (Bucket*)((uint)ptr - datoff); 1033e12c5d1SDavid du Colombier 1043e12c5d1SDavid du Colombier if(bp->magic != MAGIC) 1053e12c5d1SDavid du Colombier abort(); 1063e12c5d1SDavid du Colombier 1073e12c5d1SDavid du Colombier bp->magic = 0; 1083e12c5d1SDavid du Colombier l = &arena.btab[bp->size]; 1093e12c5d1SDavid du Colombier bp->next = *l; 1103e12c5d1SDavid du Colombier *l = bp; 1113e12c5d1SDavid du Colombier } 1123e12c5d1SDavid du Colombier 1133e12c5d1SDavid du Colombier void* 1143e12c5d1SDavid du Colombier realloc(void *ptr, size_t n) 1153e12c5d1SDavid du Colombier { 1163e12c5d1SDavid du Colombier void *new; 1173e12c5d1SDavid du Colombier uint osize; 1183e12c5d1SDavid du Colombier Bucket *bp; 1193e12c5d1SDavid du Colombier 1203e12c5d1SDavid du Colombier if(ptr == nil) 1213e12c5d1SDavid du Colombier return malloc(n); 1223e12c5d1SDavid du Colombier 1233e12c5d1SDavid du Colombier /* Find the start of the structure */ 1243e12c5d1SDavid du Colombier bp = (Bucket*)((uint)ptr - datoff); 1253e12c5d1SDavid du Colombier 1263e12c5d1SDavid du Colombier if(bp->magic != MAGIC) 1273e12c5d1SDavid du Colombier abort(); 1283e12c5d1SDavid du Colombier 1293e12c5d1SDavid du Colombier /* enough space in this bucket */ 1303e12c5d1SDavid du Colombier osize = 1<<bp->size; 1313e12c5d1SDavid du Colombier if(osize >= n) 1323e12c5d1SDavid du Colombier return ptr; 1333e12c5d1SDavid du Colombier 1343e12c5d1SDavid du Colombier new = malloc(n); 1353e12c5d1SDavid du Colombier if(new == nil) 1363e12c5d1SDavid du Colombier return nil; 1373e12c5d1SDavid du Colombier 1383e12c5d1SDavid du Colombier memmove(new, ptr, osize); 1393e12c5d1SDavid du Colombier free(ptr); 1403e12c5d1SDavid du Colombier 1413e12c5d1SDavid du Colombier return new; 1423e12c5d1SDavid du Colombier } 143