mm: reorder the preceding and size and move MM_ALLOC_BIT to size

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
wangbowen6
2022-12-15 19:55:16 +08:00
committed by Xiang Xiao
parent 8b27d60bcd
commit 723c6e52e2
14 changed files with 145 additions and 134 deletions
+8 -4
View File
@@ -134,6 +134,10 @@
#define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s) #define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
/* Get the node size */
#define SIZEOF_MM_NODE(node) ((node)->size & (~MM_MASK_BIT))
/**************************************************************************** /****************************************************************************
* Public Types * Public Types
****************************************************************************/ ****************************************************************************/
@@ -153,28 +157,28 @@ typedef size_t mmsize_t;
struct mm_allocnode_s struct mm_allocnode_s
{ {
mmsize_t preceding; /* Size of the preceding chunk */
mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0 #if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */ pid_t pid; /* The pid for caller */
# if CONFIG_MM_BACKTRACE > 0 # if CONFIG_MM_BACKTRACE > 0
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */ FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
# endif # endif
#endif #endif
mmsize_t size; /* Size of this chunk */
mmsize_t preceding; /* Size of the preceding chunk */
}; };
/* This describes a free chunk */ /* This describes a free chunk */
struct mm_freenode_s struct mm_freenode_s
{ {
mmsize_t preceding; /* Size of the preceding chunk */
mmsize_t size; /* Size of this chunk */
#if CONFIG_MM_BACKTRACE >= 0 #if CONFIG_MM_BACKTRACE >= 0
pid_t pid; /* The pid for caller */ pid_t pid; /* The pid for caller */
# if CONFIG_MM_BACKTRACE > 0 # if CONFIG_MM_BACKTRACE > 0
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */ FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
# endif # endif
#endif #endif
mmsize_t size; /* Size of this chunk */
mmsize_t preceding; /* Size of the preceding chunk */
FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */ FAR struct mm_freenode_s *flink; /* Supports a doubly linked list */
FAR struct mm_freenode_s *blink; FAR struct mm_freenode_s *blink;
}; };
+5 -4
View File
@@ -48,20 +48,21 @@ void mm_addfreechunk(FAR struct mm_heap_s *heap,
{ {
FAR struct mm_freenode_s *next; FAR struct mm_freenode_s *next;
FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *prev;
size_t nodesize = SIZEOF_MM_NODE(node);
int ndx; int ndx;
DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE); DEBUGASSERT(nodesize >= SIZEOF_MM_FREENODE);
DEBUGASSERT((node->preceding & MM_ALLOC_BIT) == 0); DEBUGASSERT((node->size & MM_ALLOC_BIT) == 0);
/* Convert the size to a nodelist index */ /* Convert the size to a nodelist index */
ndx = mm_size2ndx(node->size); ndx = mm_size2ndx(nodesize);
/* Now put the new node into the next */ /* Now put the new node into the next */
for (prev = &heap->mm_nodelist[ndx], for (prev = &heap->mm_nodelist[ndx],
next = heap->mm_nodelist[ndx].flink; next = heap->mm_nodelist[ndx].flink;
next && next->size && next->size < node->size; next && next->size && SIZEOF_MM_NODE(next) < nodesize;
prev = next, next = next->flink); prev = next, next = next->flink);
/* Does it go in mid next or at the end? */ /* Does it go in mid next or at the end? */
+8 -6
View File
@@ -40,22 +40,24 @@
static void checkcorruption_handler(FAR struct mm_allocnode_s *node, static void checkcorruption_handler(FAR struct mm_allocnode_s *node,
FAR void *arg) FAR void *arg)
{ {
if ((node->preceding & MM_ALLOC_BIT) != 0) size_t nodesize = SIZEOF_MM_NODE(node);
if ((node->size & MM_ALLOC_BIT) != 0)
{ {
assert(node->size >= SIZEOF_MM_ALLOCNODE); assert(nodesize >= SIZEOF_MM_ALLOCNODE);
} }
else else
{ {
FAR struct mm_freenode_s *fnode = (FAR void *)node; FAR struct mm_freenode_s *fnode = (FAR void *)node;
assert(node->size >= SIZEOF_MM_FREENODE); assert(nodesize >= SIZEOF_MM_FREENODE);
assert(fnode->blink->flink == fnode); assert(fnode->blink->flink == fnode);
assert(fnode->blink->size <= fnode->size); assert(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
assert(fnode->flink == NULL || assert(fnode->flink == NULL ||
fnode->flink->blink == fnode); fnode->flink->blink == fnode);
assert(fnode->flink == NULL || assert(fnode->flink == NULL ||
fnode->flink->size == 0 || SIZEOF_MM_NODE(fnode->flink) == 0 ||
fnode->flink->size >= fnode->size); SIZEOF_MM_NODE(fnode->flink) >= nodesize);
} }
} }
+4 -4
View File
@@ -92,18 +92,18 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
* (SIZEOF_MM_ALLOCNODE) or simply: * (SIZEOF_MM_ALLOCNODE) or simply:
*/ */
oldnode->size = size; oldnode->size = size | (oldnode->size & MM_MASK_BIT);
/* The old node should already be marked as allocated */ /* The old node should already be marked as allocated */
DEBUGASSERT((oldnode->preceding & MM_ALLOC_BIT) != 0); DEBUGASSERT((oldnode->size & MM_ALLOC_BIT) != 0);
/* Get and initialize the new terminal node in the heap */ /* Get and initialize the new terminal node in the heap */
newnode = (FAR struct mm_allocnode_s *) newnode = (FAR struct mm_allocnode_s *)
(blockend - SIZEOF_MM_ALLOCNODE); (blockend - SIZEOF_MM_ALLOCNODE);
newnode->size = SIZEOF_MM_ALLOCNODE; newnode->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
newnode->preceding = oldnode->size | MM_ALLOC_BIT; newnode->preceding = size;
heap->mm_heapend[region] = newnode; heap->mm_heapend[region] = newnode;
+7 -7
View File
@@ -48,6 +48,7 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler,
{ {
FAR struct mm_allocnode_s *node; FAR struct mm_allocnode_s *node;
FAR struct mm_allocnode_s *prev; FAR struct mm_allocnode_s *prev;
size_t nodesize;
#if CONFIG_MM_REGIONS > 1 #if CONFIG_MM_REGIONS > 1
int region; int region;
#else #else
@@ -75,18 +76,17 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler,
for (node = heap->mm_heapstart[region]; for (node = heap->mm_heapstart[region];
node < heap->mm_heapend[region]; node < heap->mm_heapend[region];
node = (FAR struct mm_allocnode_s *) node = (FAR struct mm_allocnode_s *)((FAR char *)node + nodesize))
((FAR char *)node + node->size))
{ {
minfo("region=%d node=%p size=%u preceding=%u (%c)\n", nodesize = SIZEOF_MM_NODE(node);
region, node, (unsigned int)node->size, minfo("region=%d node=%p size=%zu preceding=%u (%c)\n",
(unsigned int)(node->preceding & ~MM_ALLOC_BIT), region, node, nodesize, (unsigned int)node->preceding,
(node->preceding & MM_ALLOC_BIT) ? 'A' : 'F'); (node->size & MM_ALLOC_BIT) ? 'A' : 'F');
handler(node, arg); handler(node, arg);
DEBUGASSERT(prev == NULL || DEBUGASSERT(prev == NULL ||
prev->size == (node->preceding & ~MM_MASK_BIT)); SIZEOF_MM_NODE(prev) == node->preceding);
prev = node; prev = node;
} }
+19 -14
View File
@@ -72,6 +72,8 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
FAR struct mm_freenode_s *node; FAR struct mm_freenode_s *node;
FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *prev;
FAR struct mm_freenode_s *next; FAR struct mm_freenode_s *next;
size_t nodesize;
size_t prevsize;
minfo("Freeing %p\n", mem); minfo("Freeing %p\n", mem);
@@ -107,28 +109,29 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
/* Map the memory chunk into a free node */ /* Map the memory chunk into a free node */
node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE); node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE);
nodesize = SIZEOF_MM_NODE(node);
/* Sanity check against double-frees */ /* Sanity check against double-frees */
DEBUGASSERT(node->preceding & MM_ALLOC_BIT); DEBUGASSERT(node->size & MM_ALLOC_BIT);
node->preceding &= ~MM_MASK_BIT; node->size &= ~MM_ALLOC_BIT;
/* Check if the following node is free and, if so, merge it */ /* Check if the following node is free and, if so, merge it */
next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size); next = (FAR struct mm_freenode_s *)((FAR char *)node + nodesize);
DEBUGASSERT((next->preceding & ~MM_MASK_BIT) == node->size); DEBUGASSERT(next->preceding == nodesize);
if ((next->preceding & MM_ALLOC_BIT) == 0) if ((next->size & MM_ALLOC_BIT) == 0)
{ {
FAR struct mm_allocnode_s *andbeyond; FAR struct mm_allocnode_s *andbeyond;
size_t nextsize = SIZEOF_MM_NODE(next);
/* Get the node following the next node (which will /* Get the node following the next node (which will
* become the new next node). We know that we can never * become the new next node). We know that we can never
* index past the tail chunk because it is always allocated. * index past the tail chunk because it is always allocated.
*/ */
andbeyond = (FAR struct mm_allocnode_s *) andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
((FAR char *)next + next->size);
/* Remove the next node. There must be a predecessor, /* Remove the next node. There must be a predecessor,
* but there may not be a successor node. * but there may not be a successor node.
@@ -143,9 +146,9 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
/* Then merge the two chunks */ /* Then merge the two chunks */
node->size += next->size; nodesize += nextsize;
andbeyond->preceding = node->size | node->size = nodesize | (node->size & MM_MASK_BIT);
(andbeyond->preceding & MM_MASK_BIT); andbeyond->preceding = nodesize;
next = (FAR struct mm_freenode_s *)andbeyond; next = (FAR struct mm_freenode_s *)andbeyond;
} }
@@ -154,8 +157,9 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
*/ */
prev = (FAR struct mm_freenode_s *)((FAR char *)node - node->preceding); prev = (FAR struct mm_freenode_s *)((FAR char *)node - node->preceding);
DEBUGASSERT((node->preceding & ~MM_MASK_BIT) == prev->size); prevsize = SIZEOF_MM_NODE(prev);
if ((prev->preceding & MM_ALLOC_BIT) == 0) DEBUGASSERT(node->preceding == prevsize);
if ((prev->size & MM_ALLOC_BIT) == 0)
{ {
/* Remove the node. There must be a predecessor, but there may /* Remove the node. There must be a predecessor, but there may
* not be a successor node. * not be a successor node.
@@ -170,8 +174,9 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
/* Then merge the two chunks */ /* Then merge the two chunks */
prev->size += node->size; prevsize += nodesize;
next->preceding = prev->size | (next->preceding & MM_MASK_BIT); prev->size = prevsize | (prev->size & MM_MASK_BIT);
next->preceding = prevsize;
node = prev; node = prev;
} }
+3 -4
View File
@@ -137,8 +137,7 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
heap->mm_heapstart[IDX] = (FAR struct mm_allocnode_s *) heap->mm_heapstart[IDX] = (FAR struct mm_allocnode_s *)
heapbase; heapbase;
MM_ADD_BACKTRACE(heap, heap->mm_heapstart[IDX]); MM_ADD_BACKTRACE(heap, heap->mm_heapstart[IDX]);
heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE; heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
heap->mm_heapstart[IDX]->preceding = MM_ALLOC_BIT;
node = (FAR struct mm_freenode_s *) node = (FAR struct mm_freenode_s *)
(heapbase + SIZEOF_MM_ALLOCNODE); (heapbase + SIZEOF_MM_ALLOCNODE);
DEBUGASSERT((((uintptr_t)node + SIZEOF_MM_ALLOCNODE) % MM_MIN_CHUNK) == 0); DEBUGASSERT((((uintptr_t)node + SIZEOF_MM_ALLOCNODE) % MM_MIN_CHUNK) == 0);
@@ -146,8 +145,8 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
node->preceding = SIZEOF_MM_ALLOCNODE; node->preceding = SIZEOF_MM_ALLOCNODE;
heap->mm_heapend[IDX] = (FAR struct mm_allocnode_s *) heap->mm_heapend[IDX] = (FAR struct mm_allocnode_s *)
(heapend - SIZEOF_MM_ALLOCNODE); (heapend - SIZEOF_MM_ALLOCNODE);
heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE; heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
heap->mm_heapend[IDX]->preceding = node->size | MM_ALLOC_BIT; heap->mm_heapend[IDX]->preceding = node->size;
MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]); MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]);
#undef IDX #undef IDX
+18 -17
View File
@@ -39,38 +39,38 @@
static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg) static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
{ {
FAR struct mallinfo *info = arg; FAR struct mallinfo *info = arg;
size_t nodesize = SIZEOF_MM_NODE(node);
minfo("node=%p size=%u preceding=%u (%c)\n", minfo("node=%p size=%zu preceding=%u (%c)\n",
node, (unsigned int)node->size, node, nodesize, (unsigned int)node->preceding,
(unsigned int)(node->preceding & ~MM_ALLOC_BIT), (node->size & MM_ALLOC_BIT) ? 'A' : 'F');
(node->preceding & MM_ALLOC_BIT) ? 'A' : 'F');
/* Check if the node corresponds to an allocated memory chunk */ /* Check if the node corresponds to an allocated memory chunk */
if ((node->preceding & MM_ALLOC_BIT) != 0) if ((node->size & MM_ALLOC_BIT) != 0)
{ {
DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE); DEBUGASSERT(nodesize >= SIZEOF_MM_ALLOCNODE);
info->aordblks++; info->aordblks++;
info->uordblks += node->size; info->uordblks += nodesize;
} }
else else
{ {
FAR struct mm_freenode_s *fnode = (FAR void *)node; FAR struct mm_freenode_s *fnode = (FAR void *)node;
DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE); DEBUGASSERT(nodesize >= SIZEOF_MM_FREENODE);
DEBUGASSERT(fnode->blink->flink == fnode); DEBUGASSERT(fnode->blink->flink == fnode);
DEBUGASSERT(fnode->blink->size <= fnode->size); DEBUGASSERT(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
DEBUGASSERT(fnode->flink == NULL || DEBUGASSERT(fnode->flink == NULL ||
fnode->flink->blink == fnode); fnode->flink->blink == fnode);
DEBUGASSERT(fnode->flink == NULL || DEBUGASSERT(fnode->flink == NULL ||
fnode->flink->size == 0 || SIZEOF_MM_NODE(fnode->flink) == 0 ||
fnode->flink->size >= fnode->size); SIZEOF_MM_NODE(fnode->flink) >= nodesize);
info->ordblks++; info->ordblks++;
info->fordblks += node->size; info->fordblks += nodesize;
if (node->size > (size_t)info->mxordblk) if (node->size > (size_t)info->mxordblk)
{ {
info->mxordblk = node->size; info->mxordblk = nodesize;
} }
} }
} }
@@ -79,12 +79,13 @@ static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
FAR void *arg) FAR void *arg)
{ {
FAR struct mallinfo_task *info = arg; FAR struct mallinfo_task *info = arg;
size_t nodesize = SIZEOF_MM_NODE(node);
/* Check if the node corresponds to an allocated memory chunk */ /* Check if the node corresponds to an allocated memory chunk */
if ((node->preceding & MM_ALLOC_BIT) != 0) if ((node->size & MM_ALLOC_BIT) != 0)
{ {
DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE); DEBUGASSERT(nodesize >= SIZEOF_MM_ALLOCNODE);
#if CONFIG_MM_BACKTRACE < 0 #if CONFIG_MM_BACKTRACE < 0
if (info->pid == -1) if (info->pid == -1)
#else #else
@@ -92,13 +93,13 @@ static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
#endif #endif
{ {
info->aordblks++; info->aordblks++;
info->uordblks += node->size; info->uordblks += nodesize;
} }
} }
else if (info->pid == -2) else if (info->pid == -2)
{ {
info->aordblks++; info->aordblks++;
info->uordblks += node->size; info->uordblks += nodesize;
} }
} }
+12 -11
View File
@@ -106,6 +106,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
{ {
FAR struct mm_freenode_s *node; FAR struct mm_freenode_s *node;
size_t alignsize; size_t alignsize;
size_t nodesize;
FAR void *ret = NULL; FAR void *ret = NULL;
int ndx; int ndx;
@@ -156,11 +157,14 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
* other mm_nodelist[] entries. * other mm_nodelist[] entries.
*/ */
for (node = heap->mm_nodelist[ndx].flink; for (node = heap->mm_nodelist[ndx].flink; node; node = node->flink)
node && node->size < alignsize;
node = node->flink)
{ {
DEBUGASSERT(node->blink->flink == node); DEBUGASSERT(node->blink->flink == node);
nodesize = SIZEOF_MM_NODE(node);
if (nodesize >= alignsize)
{
break;
}
} }
/* If we found a node with non-zero size, then this is one to use. Since /* If we found a node with non-zero size, then this is one to use. Since
@@ -192,13 +196,12 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
* allocation. * allocation.
*/ */
remaining = node->size - alignsize; remaining = nodesize - alignsize;
if (remaining >= SIZEOF_MM_FREENODE) if (remaining >= SIZEOF_MM_FREENODE)
{ {
/* Get a pointer to the next node in physical memory */ /* Get a pointer to the next node in physical memory */
next = (FAR struct mm_freenode_s *) next = (FAR struct mm_freenode_s *)(((FAR char *)node) + nodesize);
(((FAR char *)node) + node->size);
/* Create the remainder node */ /* Create the remainder node */
@@ -212,11 +215,9 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
node->size = alignsize; node->size = alignsize;
/* Adjust the 'preceding' size of the (old) next node, preserving /* Adjust the 'preceding' size of the (old) next node. */
* the allocated flag.
*/
next->preceding = remaining | (next->preceding & MM_MASK_BIT); next->preceding = remaining;
/* Add the remainder back into the nodelist */ /* Add the remainder back into the nodelist */
@@ -225,7 +226,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
/* Handle the case of an exact size match */ /* Handle the case of an exact size match */
node->preceding |= MM_ALLOC_BIT; node->size |= MM_ALLOC_BIT;
ret = (FAR void *)((FAR char *)node + SIZEOF_MM_ALLOCNODE); ret = (FAR void *)((FAR char *)node + SIZEOF_MM_ALLOCNODE);
} }
+2 -2
View File
@@ -60,7 +60,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
/* Sanity check against double-frees */ /* Sanity check against double-frees */
DEBUGASSERT(node->preceding & MM_ALLOC_BIT); DEBUGASSERT(node->size & MM_ALLOC_BIT);
return node->size - SIZEOF_MM_ALLOCNODE; return SIZEOF_MM_NODE(node) - SIZEOF_MM_ALLOCNODE;
} }
+9 -10
View File
@@ -148,14 +148,12 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
FAR struct mm_allocnode_s *next; FAR struct mm_allocnode_s *next;
FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *prev;
size_t precedingsize; size_t precedingsize;
size_t newnodesize;
/* Mark node free */
node->preceding &= ~MM_MASK_BIT;
/* Get the node the next node after the allocation. */ /* Get the node the next node after the allocation. */
next = (FAR struct mm_allocnode_s *)((FAR char *)node + node->size); next = (FAR struct mm_allocnode_s *)
((FAR char *)node + SIZEOF_MM_NODE(node));
prev = (FAR struct mm_freenode_s *) prev = (FAR struct mm_freenode_s *)
((FAR char *)node - node->preceding); ((FAR char *)node - node->preceding);
@@ -195,7 +193,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
* set up the node size. * set up the node size.
*/ */
if ((prev->preceding & MM_ALLOC_BIT) == 0) if ((prev->size & MM_ALLOC_BIT) == 0)
{ {
/* Remove the node. There must be a predecessor, but there may /* Remove the node. There must be a predecessor, but there may
* not be a successor node. * not be a successor node.
@@ -216,18 +214,19 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
/* Set up the size of the new node */ /* Set up the size of the new node */
newnode->size = (uintptr_t)next - (uintptr_t)newnode; newnodesize = (uintptr_t)next - (uintptr_t)newnode;
newnode->preceding = precedingsize | MM_ALLOC_BIT; newnode->size = newnodesize | MM_ALLOC_BIT;
newnode->preceding = precedingsize;
/* Fix the preceding size of the next node */ /* Fix the preceding size of the next node */
next->preceding = newnode->size | (next->preceding & MM_ALLOC_BIT); next->preceding = newnodesize;
/* Convert the newnode chunk size back into malloc-compatible size by /* Convert the newnode chunk size back into malloc-compatible size by
* subtracting the header size SIZEOF_MM_ALLOCNODE. * subtracting the header size SIZEOF_MM_ALLOCNODE.
*/ */
allocsize = newnode->size - SIZEOF_MM_ALLOCNODE; allocsize = newnodesize - SIZEOF_MM_ALLOCNODE;
/* Add the original, newly freed node to the free nodelist */ /* Add the original, newly freed node to the free nodelist */
+10 -9
View File
@@ -54,10 +54,11 @@
static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg) static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
{ {
pid_t pid = *(FAR pid_t *)arg; pid_t pid = *(FAR pid_t *)arg;
size_t nodesize = SIZEOF_MM_NODE(node);
if ((node->preceding & MM_ALLOC_BIT) != 0) if ((node->size & MM_ALLOC_BIT) != 0)
{ {
DEBUGASSERT(node->size >= SIZEOF_MM_ALLOCNODE); DEBUGASSERT(nodesize >= SIZEOF_MM_ALLOCNODE);
#if CONFIG_MM_BACKTRACE < 0 #if CONFIG_MM_BACKTRACE < 0
if (pid == -1) if (pid == -1)
#else #else
@@ -66,7 +67,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
{ {
#if CONFIG_MM_BACKTRACE < 0 #if CONFIG_MM_BACKTRACE < 0
syslog(LOG_INFO, "%12zu%*p\n", syslog(LOG_INFO, "%12zu%*p\n",
(size_t)node->size, MM_PTR_FMT_WIDTH, nodesize, MM_PTR_FMT_WIDTH,
((FAR char *)node + SIZEOF_MM_ALLOCNODE)); ((FAR char *)node + SIZEOF_MM_ALLOCNODE));
#else #else
# if CONFIG_MM_BACKTRACE > 0 # if CONFIG_MM_BACKTRACE > 0
@@ -85,7 +86,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
# endif # endif
syslog(LOG_INFO, "%6d%12zu%*p%s\n", syslog(LOG_INFO, "%6d%12zu%*p%s\n",
(int)node->pid, (size_t)node->size, MM_PTR_FMT_WIDTH, (int)node->pid, nodesize, MM_PTR_FMT_WIDTH,
((FAR char *)node + SIZEOF_MM_ALLOCNODE), buf); ((FAR char *)node + SIZEOF_MM_ALLOCNODE), buf);
#endif #endif
} }
@@ -94,19 +95,19 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
{ {
FAR struct mm_freenode_s *fnode = (FAR void *)node; FAR struct mm_freenode_s *fnode = (FAR void *)node;
DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE); DEBUGASSERT(nodesize >= SIZEOF_MM_FREENODE);
DEBUGASSERT(fnode->blink->flink == fnode); DEBUGASSERT(fnode->blink->flink == fnode);
DEBUGASSERT(fnode->blink->size <= fnode->size); DEBUGASSERT(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
DEBUGASSERT(fnode->flink == NULL || DEBUGASSERT(fnode->flink == NULL ||
fnode->flink->blink == fnode); fnode->flink->blink == fnode);
DEBUGASSERT(fnode->flink == NULL || DEBUGASSERT(fnode->flink == NULL ||
fnode->flink->size == 0 || SIZEOF_MM_NODE(fnode->flink) == 0 ||
fnode->flink->size >= fnode->size); SIZEOF_MM_NODE(fnode->flink) >= nodesize);
if (pid <= -2) if (pid <= -2)
{ {
syslog(LOG_INFO, "%12zu%*p\n", syslog(LOG_INFO, "%12zu%*p\n",
(size_t)node->size, MM_PTR_FMT_WIDTH, nodesize, MM_PTR_FMT_WIDTH,
((FAR char *)node + SIZEOF_MM_ALLOCNODE)); ((FAR char *)node + SIZEOF_MM_ALLOCNODE));
} }
} }
+27 -28
View File
@@ -134,12 +134,12 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
/* We need to hold the MM mutex while we muck with the nodelist. */ /* We need to hold the MM mutex while we muck with the nodelist. */
DEBUGVERIFY(mm_lock(heap)); DEBUGVERIFY(mm_lock(heap));
DEBUGASSERT(oldnode->preceding & MM_ALLOC_BIT); DEBUGASSERT(oldnode->size & MM_ALLOC_BIT);
DEBUGASSERT(mm_heapmember(heap, oldmem)); DEBUGASSERT(mm_heapmember(heap, oldmem));
/* Check if this is a request to reduce the size of the allocation. */ /* Check if this is a request to reduce the size of the allocation. */
oldsize = oldnode->size; oldsize = SIZEOF_MM_NODE(oldnode);
if (newsize <= oldsize) if (newsize <= oldsize)
{ {
/* Handle the special case where we are not going to change the size /* Handle the special case where we are not going to change the size
@@ -149,8 +149,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (newsize < oldsize) if (newsize < oldsize)
{ {
mm_shrinkchunk(heap, oldnode, newsize); mm_shrinkchunk(heap, oldnode, newsize);
kasan_poison((FAR char *)oldnode + oldnode->size, kasan_poison((FAR char *)oldnode + SIZEOF_MM_NODE(oldnode),
oldsize - oldnode->size); oldsize - SIZEOF_MM_NODE(oldnode));
} }
/* Then return the original address */ /* Then return the original address */
@@ -166,18 +166,17 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
* best decision * best decision
*/ */
next = (FAR struct mm_freenode_s *) next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldsize);
((FAR char *)oldnode + oldnode->size); if ((next->size & MM_ALLOC_BIT) == 0)
if ((next->preceding & MM_ALLOC_BIT) == 0)
{ {
nextsize = next->size; nextsize = SIZEOF_MM_NODE(next);
} }
prev = (FAR struct mm_freenode_s *) prev = (FAR struct mm_freenode_s *)
((FAR char *)oldnode - (oldnode->preceding & ~MM_MASK_BIT)); ((FAR char *)oldnode - oldnode->preceding);
if ((prev->preceding & MM_ALLOC_BIT) == 0) if ((prev->size & MM_ALLOC_BIT) == 0)
{ {
prevsize = prev->size; prevsize = SIZEOF_MM_NODE(prev);
} }
/* Now, check if we can extend the current allocation or not */ /* Now, check if we can extend the current allocation or not */
@@ -185,6 +184,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
if (nextsize + prevsize + oldsize >= newsize) if (nextsize + prevsize + oldsize >= newsize)
{ {
size_t needed = newsize - oldsize; size_t needed = newsize - oldsize;
size_t nodesize = oldsize;
size_t takeprev; size_t takeprev;
size_t takenext; size_t takenext;
@@ -271,12 +271,13 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
* it back into the free list * it back into the free list
*/ */
prev->size -= takeprev; prevsize -= takeprev;
DEBUGASSERT(prev->size >= SIZEOF_MM_FREENODE); DEBUGASSERT(prevsize >= SIZEOF_MM_FREENODE);
newnode->size = oldsize + takeprev; prev->size = prevsize;
newnode->preceding = prev->size | MM_ALLOC_BIT; nodesize += takeprev;
next->preceding = newnode->size | newnode->size = nodesize | MM_MASK_BIT;
(next->preceding & MM_MASK_BIT); newnode->preceding = prevsize;
next->preceding = nodesize;
/* Return the previous free node to the nodelist /* Return the previous free node to the nodelist
* (with the new size) * (with the new size)
@@ -288,10 +289,9 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
{ {
/* Yes.. update its size (newnode->preceding is already set) */ /* Yes.. update its size (newnode->preceding is already set) */
newnode->size += oldsize; nodesize += prevsize;
newnode->preceding |= MM_ALLOC_BIT; newnode->size = nodesize | MM_ALLOC_BIT;
next->preceding = newnode->size | next->preceding = nodesize;
(next->preceding & MM_MASK_BIT);
} }
newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE); newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE);
@@ -328,7 +328,8 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
/* Extend the node into the next chunk */ /* Extend the node into the next chunk */
oldnode->size += takenext; nodesize += takenext;
oldnode->size = nodesize | (oldnode->size & MM_MASK_BIT);
/* Did we consume the entire preceding chunk? */ /* Did we consume the entire preceding chunk? */
@@ -339,12 +340,11 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
*/ */
newnode = (FAR struct mm_freenode_s *) newnode = (FAR struct mm_freenode_s *)
((FAR char *)oldnode + oldnode->size); ((FAR char *)oldnode + nodesize);
newnode->size = nextsize - takenext; newnode->size = nextsize - takenext;
DEBUGASSERT(newnode->size >= SIZEOF_MM_FREENODE); DEBUGASSERT(newnode->size >= SIZEOF_MM_FREENODE);
newnode->preceding = oldnode->size; newnode->preceding = nodesize;
andbeyond->preceding = newnode->size | andbeyond->preceding = newnode->size;
(andbeyond->preceding & MM_MASK_BIT);
/* Add the new free node to the nodelist (with the new size) */ /* Add the new free node to the nodelist (with the new size) */
@@ -354,8 +354,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
{ {
/* Yes, just update some pointers. */ /* Yes, just update some pointers. */
andbeyond->preceding = oldnode->size | andbeyond->preceding = nodesize;
(andbeyond->preceding & MM_MASK_BIT);
} }
} }
+12 -13
View File
@@ -53,24 +53,25 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
FAR struct mm_allocnode_s *node, size_t size) FAR struct mm_allocnode_s *node, size_t size)
{ {
FAR struct mm_freenode_s *next; FAR struct mm_freenode_s *next;
size_t nodesize = SIZEOF_MM_NODE(node);
DEBUGASSERT((size & MM_GRAN_MASK) == 0); DEBUGASSERT((size & MM_GRAN_MASK) == 0);
/* Get a reference to the next node */ /* Get a reference to the next node */
next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size); next = (FAR struct mm_freenode_s *)((FAR char *)node + nodesize);
/* Check if it is free */ /* Check if it is free */
if ((next->preceding & MM_ALLOC_BIT) == 0) if ((next->size & MM_ALLOC_BIT) == 0)
{ {
FAR struct mm_allocnode_s *andbeyond; FAR struct mm_allocnode_s *andbeyond;
FAR struct mm_freenode_s *newnode; FAR struct mm_freenode_s *newnode;
size_t nextsize = SIZEOF_MM_NODE(next);
/* Get the chunk next the next node (which could be the tail chunk) */ /* Get the chunk next the next node (which could be the tail chunk) */
andbeyond = (FAR struct mm_allocnode_s *) andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
((FAR char *)next + next->size);
/* Remove the next node. There must be a predecessor, but there may /* Remove the next node. There must be a predecessor, but there may
* not be a successor node. * not be a successor node.
@@ -91,11 +92,10 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
/* Set up the size of the new node */ /* Set up the size of the new node */
newnode->size = next->size + node->size - size; newnode->size = nextsize + nodesize - size;
newnode->preceding = size; newnode->preceding = size;
node->size = size; node->size = size | (node->size & MM_MASK_BIT);
andbeyond->preceding = newnode->size | andbeyond->preceding = newnode->size;
(andbeyond->preceding & MM_MASK_BIT);
/* Add the new node to the freenodelist */ /* Add the new node to the freenodelist */
@@ -106,7 +106,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
* chunk to be shrunk. * chunk to be shrunk.
*/ */
else if (node->size >= size + SIZEOF_MM_FREENODE) else if (nodesize >= size + SIZEOF_MM_FREENODE)
{ {
FAR struct mm_freenode_s *newnode; FAR struct mm_freenode_s *newnode;
@@ -118,11 +118,10 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
/* Set up the size of the new node */ /* Set up the size of the new node */
newnode->size = node->size - size; newnode->size = nodesize - size;
newnode->preceding = size; newnode->preceding = size;
node->size = size; node->size = size | (node->size & MM_MASK_BIT);
next->preceding = newnode->size | next->preceding = newnode->size;
(next->preceding & MM_MASK_BIT);
/* Add the new node to the freenodelist */ /* Add the new node to the freenodelist */