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 <kevin@koconnor.net>
This commit is contained in:
parent
41acaa8274
commit
7af8d120fb
10
src/list.h
10
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) \
|
||||
|
|
72
src/malloc.c
72
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue