1 #include "alloc.h" 2 3 void *malloc(size_t size) 4 { 5 return memalign(sizeof(long), size); 6 } 7 8 void *calloc(size_t nmemb, size_t size) 9 { 10 void *ptr = malloc(nmemb * size); 11 if (ptr) 12 memset(ptr, 0, nmemb * size); 13 return ptr; 14 } 15 16 #define METADATA_EXTRA (2 * sizeof(uintptr_t)) 17 #define OFS_SLACK (-2 * sizeof(uintptr_t)) 18 #define OFS_SIZE (-sizeof(uintptr_t)) 19 20 static inline void *block_begin(void *mem) 21 { 22 uintptr_t slack = *(uintptr_t *)(mem + OFS_SLACK); 23 return mem - slack; 24 } 25 26 static inline uintptr_t block_size(void *mem) 27 { 28 return *(uintptr_t *)(mem + OFS_SIZE); 29 } 30 31 void free(void *ptr) 32 { 33 if (!alloc_ops->free) 34 return; 35 36 void *base = block_begin(ptr); 37 uintptr_t sz = block_size(ptr); 38 39 alloc_ops->free(base, sz); 40 } 41 42 void *memalign(size_t alignment, size_t size) 43 { 44 void *p; 45 uintptr_t blkalign; 46 uintptr_t mem; 47 48 assert(alloc_ops && alloc_ops->memalign); 49 if (alignment <= sizeof(uintptr_t)) 50 alignment = sizeof(uintptr_t); 51 else 52 size += alignment - 1; 53 54 blkalign = MAX(alignment, alloc_ops->align_min); 55 size = ALIGN(size + METADATA_EXTRA, alloc_ops->align_min); 56 p = alloc_ops->memalign(blkalign, size); 57 58 /* Leave room for metadata before aligning the result. */ 59 mem = (uintptr_t)p + METADATA_EXTRA; 60 mem = ALIGN(mem, alignment); 61 62 /* Write the metadata */ 63 *(uintptr_t *)(mem + OFS_SLACK) = mem - (uintptr_t)p; 64 *(uintptr_t *)(mem + OFS_SIZE) = size; 65 return (void *)mem; 66 } 67