diff options
author | Patrick Georgi <patrick.georgi@coresystems.de> | 2008-09-02 15:49:32 +0000 |
---|---|---|
committer | Patrick Georgi <patrick.georgi@coresystems.de> | 2008-09-02 15:49:32 +0000 |
commit | 5ccfa1ac7994888f57c60b80fff80e350ab3f16c (patch) | |
tree | 31e7f480a71a9f2f7a4670f82ed3f69c0e293719 | |
parent | 56471f14db710f9368a53fa709fe79465220f245 (diff) |
Add memalign(align, size).
Signed-off-by: Patrick Georgi <patrick.georgi@coresystems.de>
Acked-by: Jordan Crouse <jordan.crouse@amd.com>
git-svn-id: svn://svn.coreboot.org/coreboot/trunk@3559 2b7e53f0-3cfb-0310-b3e9-8179ed1497e1
-rw-r--r-- | payloads/libpayload/include/libpayload.h | 1 | ||||
-rw-r--r-- | payloads/libpayload/libc/malloc.c | 35 |
2 files changed, 28 insertions, 8 deletions
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); |