From 5ccfa1ac7994888f57c60b80fff80e350ab3f16c Mon Sep 17 00:00:00 2001 From: Patrick Georgi Date: Tue, 2 Sep 2008 15:49:32 +0000 Subject: Add memalign(align, size). Signed-off-by: Patrick Georgi Acked-by: Jordan Crouse git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3559 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1 --- payloads/libpayload/include/libpayload.h | 1 + payloads/libpayload/libc/malloc.c | 35 ++++++++++++++++++++++++-------- 2 files changed, 28 insertions(+), 8 deletions(-) (limited to 'payloads') diff --git a/payloads/libpayload/include/libpayload.h b/payloads/libpayload/include/libpayload.h index 7b1d5750bf..cc50fd0671 100644 --- a/payloads/libpayload/include/libpayload.h +++ b/payloads/libpayload/include/libpayload.h @@ -221,6 +221,7 @@ void free(void *ptr); void *malloc(size_t size); void *calloc(size_t nmemb, size_t size); void *realloc(void *ptr, size_t size); +void *memalign(size_t align, size_t size); /** @} */ /** diff --git a/payloads/libpayload/libc/malloc.c b/payloads/libpayload/libc/malloc.c index 3c6cf5d833..6dc6aab138 100644 --- a/payloads/libpayload/libc/malloc.c +++ b/payloads/libpayload/libc/malloc.c @@ -72,7 +72,7 @@ static void setup(void) *((hdrtype_t *) hstart) = FREE_BLOCK(size); } -static void *alloc(int len) +static void *alloc(int len, int align) { hdrtype_t header; void *ptr = hstart; @@ -92,13 +92,20 @@ static void *alloc(int len) header = *((hdrtype_t *) ptr); int size = SIZE(header); - if (!HAS_MAGIC(header) || size == 0) { + if (!HAS_MAGIC(header)) { printf("memory allocator panic.\n"); halt(); } if (header & FLAG_FREE) { - if (len <= size) { + int realaddr = (int)(ptr + HDRSIZE); + int overhead = ((realaddr+align-1) & ~(align-1)) - realaddr; + if (len + overhead <= size) { + if (overhead != 0) { + *((hdrtype_t *) ptr) = FREE_BLOCK(overhead - HDRSIZE); + ptr += overhead; + size -= overhead; + } void *nptr = ptr + (HDRSIZE + len); int nsize = size - (HDRSIZE + len); @@ -186,13 +193,13 @@ void free(void *ptr) void *malloc(size_t size) { - return alloc(size); + return alloc(size, 1); } void *calloc(size_t nmemb, size_t size) { size_t total = nmemb * size; - void *ptr = alloc(total); + void *ptr = alloc(total, 1); if (ptr) memset(ptr, 0, total); @@ -206,7 +213,7 @@ void *realloc(void *ptr, size_t size) unsigned int osize; if (ptr == NULL) - return alloc(size); + return alloc(size, 1); pptr = ptr - HDRSIZE; @@ -222,7 +229,7 @@ void *realloc(void *ptr, size_t size) * reallocated the new space. */ free(ptr); - ret = alloc(size); + ret = alloc(size, 1); /* * if ret == NULL, then doh - failure. @@ -237,11 +244,23 @@ void *realloc(void *ptr, size_t size) return ret; } +/** + * Allocate an aligned chunk of memory + * + * @param align alignment, must be power of two + * @param size size of chunk in bytes + * @return Return the address of such a memory region or NULL + */ +void *memalign(size_t align, size_t size) +{ + return alloc(size, align); +} + /* This is for debugging purposes. */ #ifdef TEST void print_malloc_map(void) { - void *ptr = hstart; +void *ptr = hstart; while (ptr < hend) { hdrtype_t hdr = *((hdrtype_t *) ptr); -- cgit v1.2.3