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