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 assert(alloc_ops && alloc_ops->memalign); 50 if (alignment <= sizeof(uintptr_t)) 51 alignment = sizeof(uintptr_t); 52 else 53 size += alignment - 1; 54 55 blkalign = MAX(alignment, alloc_ops->align_min); 56 size = ALIGN(size + METADATA_EXTRA, alloc_ops->align_min); 57 p = alloc_ops->memalign(blkalign, size); 58 59 /* Leave room for metadata before aligning the result. */ 60 mem = (uintptr_t)p + METADATA_EXTRA; 61 mem = ALIGN(mem, alignment); 62 63 /* Write the metadata */ 64 *(uintptr_t *)(mem + OFS_SLACK) = mem - (uintptr_t)p; 65 *(uintptr_t *)(mem + OFS_SIZE) = size; 66 return (void *)mem; 67 } 68