From 7af8d120fba60669843726fed9b470e4ea6ac05e Mon Sep 17 00:00:00 2001 From: Kevin O'Connor Date: Mon, 28 Sep 2015 22:20:27 -0400 Subject: malloc: Introduce common helper alloc_new_detail() Introduce helper for finding temp space to hold an "allocation detail struct" and use it in both alloc_add() and _malloc(). Signed-off-by: Kevin O'Connor --- src/list.h | 10 +++++++++ src/malloc.c | 72 +++++++++++++++++++++++++++++++----------------------------- 2 files changed, 47 insertions(+), 35 deletions(-) diff --git a/src/list.h b/src/list.h index de656b9..94512e3 100644 --- a/src/list.h +++ b/src/list.h @@ -61,6 +61,16 @@ hlist_add_after(struct hlist_node *n, struct hlist_node *prev) hlist_add(n, &prev->next); } +static inline void +hlist_replace(struct hlist_node *old, struct hlist_node *new) +{ + new->next = old->next; + if (new->next) + new->next->pprev = &new->next; + new->pprev = old->pprev; + *new->pprev = new; +} + #define hlist_for_each_entry(pos, head, member) \ for (pos = container_of((head)->first, typeof(*pos), member) \ ; pos != container_of(NULL, typeof(*pos), member) \ diff --git a/src/malloc.c b/src/malloc.c index db451ce..c41a0cb 100644 --- a/src/malloc.c +++ b/src/malloc.c @@ -57,8 +57,6 @@ alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) void *newallocend = (void*)ALIGN_DOWN((u32)allocend - size, align); if (newallocend >= dataend && newallocend <= allocend) { // Found space - now reserve it. - if (!fill) - fill = newallocend; fill->data = newallocend; fill->dataend = newallocend + size; fill->allocend = allocend; @@ -71,6 +69,28 @@ alloc_new(struct zone_s *zone, u32 size, u32 align, struct allocinfo_s *fill) return NULL; } +// Reserve space for a 'struct allocdetail_s' and fill +static struct allocdetail_s * +alloc_new_detail(struct allocdetail_s *temp) +{ + struct allocdetail_s *detail = alloc_new( + &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail) { + detail = alloc_new(&ZoneTmpLow, sizeof(*detail) + , MALLOC_MIN_ALIGN, &temp->detailinfo); + if (!detail) { + warn_noalloc(); + return NULL; + } + } + + // Fill final 'detail' allocation from data in 'temp' + memcpy(detail, temp, sizeof(*detail)); + hlist_replace(&temp->detailinfo.node, &detail->detailinfo.node); + hlist_replace(&temp->datainfo.node, &detail->datainfo.node); + return detail; +} + // Add new memory to a zone static void alloc_add(struct zone_s *zone, void *start, void *end) @@ -85,29 +105,15 @@ alloc_add(struct zone_s *zone, void *start, void *end) // Add space using temporary allocation info. struct allocdetail_s tempdetail; + tempdetail.handle = MALLOC_DEFAULT_HANDLE; tempdetail.datainfo.data = tempdetail.datainfo.dataend = start; tempdetail.datainfo.allocend = end; hlist_add(&tempdetail.datainfo.node, pprev); // Allocate final allocation info. - struct allocdetail_s *detail = alloc_new( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = alloc_new(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) { - hlist_del(&tempdetail.datainfo.node); - warn_noalloc(); - return; - } - } - - // Replace temp alloc space with final alloc space - pprev = tempdetail.datainfo.node.pprev; - hlist_del(&tempdetail.datainfo.node); - memcpy(&detail->datainfo, &tempdetail.datainfo, sizeof(detail->datainfo)); - detail->handle = MALLOC_DEFAULT_HANDLE; - hlist_add(&detail->datainfo.node, pprev); + struct allocdetail_s *detail = alloc_new_detail(&tempdetail); + if (!detail) + hlist_del(&tempdetail.datainfo.node); } // Release space allocated with alloc_new() @@ -232,23 +238,19 @@ _malloc(struct zone_s *zone, u32 size, u32 align) if (!size) return NULL; - // Find and reserve space for bookkeeping. - struct allocdetail_s *detail = alloc_new( - &ZoneTmpHigh, sizeof(*detail), MALLOC_MIN_ALIGN, NULL); - if (!detail) { - detail = alloc_new(&ZoneTmpLow, sizeof(*detail) - , MALLOC_MIN_ALIGN, NULL); - if (!detail) - return NULL; - } - detail->handle = MALLOC_DEFAULT_HANDLE; - // Find and reserve space for main allocation - void *data = alloc_new(zone, size, align, &detail->datainfo); + struct allocdetail_s tempdetail; + tempdetail.handle = MALLOC_DEFAULT_HANDLE; + void *data = alloc_new(zone, size, align, &tempdetail.datainfo); if (!CONFIG_MALLOC_UPPERMEMORY && !data && zone == &ZoneLow) - data = zonelow_expand(size, align, &detail->datainfo); - if (!data) { - alloc_free(&detail->detailinfo); + data = zonelow_expand(size, align, &tempdetail.datainfo); + if (!data) + return NULL; + + // Find and reserve space for bookkeeping. + struct allocdetail_s *detail = alloc_new_detail(&tempdetail); + if (!detail) { + alloc_free(&tempdetail.datainfo); return NULL; } -- cgit v1.1