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:
parent
8b27d60bcd
commit
723c6e52e2
@ -134,6 +134,10 @@
|
||||
|
||||
#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
|
||||
****************************************************************************/
|
||||
@ -153,28 +157,28 @@ typedef size_t mmsize_t;
|
||||
|
||||
struct mm_allocnode_s
|
||||
{
|
||||
mmsize_t preceding; /* Size of the preceding chunk */
|
||||
mmsize_t size; /* Size of this chunk */
|
||||
#if CONFIG_MM_BACKTRACE >= 0
|
||||
pid_t pid; /* The pid for caller */
|
||||
# if CONFIG_MM_BACKTRACE > 0
|
||||
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
|
||||
# endif
|
||||
#endif
|
||||
mmsize_t size; /* Size of this chunk */
|
||||
mmsize_t preceding; /* Size of the preceding chunk */
|
||||
};
|
||||
|
||||
/* This describes a free chunk */
|
||||
|
||||
struct mm_freenode_s
|
||||
{
|
||||
mmsize_t preceding; /* Size of the preceding chunk */
|
||||
mmsize_t size; /* Size of this chunk */
|
||||
#if CONFIG_MM_BACKTRACE >= 0
|
||||
pid_t pid; /* The pid for caller */
|
||||
# if CONFIG_MM_BACKTRACE > 0
|
||||
FAR void *backtrace[CONFIG_MM_BACKTRACE]; /* The backtrace buffer for caller */
|
||||
# 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 *blink;
|
||||
};
|
||||
|
@ -48,20 +48,21 @@ void mm_addfreechunk(FAR struct mm_heap_s *heap,
|
||||
{
|
||||
FAR struct mm_freenode_s *next;
|
||||
FAR struct mm_freenode_s *prev;
|
||||
size_t nodesize = SIZEOF_MM_NODE(node);
|
||||
int ndx;
|
||||
|
||||
DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE);
|
||||
DEBUGASSERT((node->preceding & MM_ALLOC_BIT) == 0);
|
||||
DEBUGASSERT(nodesize >= SIZEOF_MM_FREENODE);
|
||||
DEBUGASSERT((node->size & MM_ALLOC_BIT) == 0);
|
||||
|
||||
/* Convert the size to a nodelist index */
|
||||
|
||||
ndx = mm_size2ndx(node->size);
|
||||
ndx = mm_size2ndx(nodesize);
|
||||
|
||||
/* Now put the new node into the next */
|
||||
|
||||
for (prev = &heap->mm_nodelist[ndx],
|
||||
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);
|
||||
|
||||
/* Does it go in mid next or at the end? */
|
||||
|
@ -40,22 +40,24 @@
|
||||
static void checkcorruption_handler(FAR struct mm_allocnode_s *node,
|
||||
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
|
||||
{
|
||||
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->size <= fnode->size);
|
||||
assert(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
|
||||
assert(fnode->flink == NULL ||
|
||||
fnode->flink->blink == fnode);
|
||||
assert(fnode->flink == NULL ||
|
||||
fnode->flink->size == 0 ||
|
||||
fnode->flink->size >= fnode->size);
|
||||
SIZEOF_MM_NODE(fnode->flink) == 0 ||
|
||||
SIZEOF_MM_NODE(fnode->flink) >= nodesize);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,18 +92,18 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
|
||||
* (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 */
|
||||
|
||||
DEBUGASSERT((oldnode->preceding & MM_ALLOC_BIT) != 0);
|
||||
DEBUGASSERT((oldnode->size & MM_ALLOC_BIT) != 0);
|
||||
|
||||
/* Get and initialize the new terminal node in the heap */
|
||||
|
||||
newnode = (FAR struct mm_allocnode_s *)
|
||||
(blockend - SIZEOF_MM_ALLOCNODE);
|
||||
newnode->size = SIZEOF_MM_ALLOCNODE;
|
||||
newnode->preceding = oldnode->size | MM_ALLOC_BIT;
|
||||
newnode->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
|
||||
newnode->preceding = size;
|
||||
|
||||
heap->mm_heapend[region] = newnode;
|
||||
|
||||
|
@ -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 *prev;
|
||||
size_t nodesize;
|
||||
#if CONFIG_MM_REGIONS > 1
|
||||
int region;
|
||||
#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];
|
||||
node < heap->mm_heapend[region];
|
||||
node = (FAR struct mm_allocnode_s *)
|
||||
((FAR char *)node + node->size))
|
||||
node = (FAR struct mm_allocnode_s *)((FAR char *)node + nodesize))
|
||||
{
|
||||
minfo("region=%d node=%p size=%u preceding=%u (%c)\n",
|
||||
region, node, (unsigned int)node->size,
|
||||
(unsigned int)(node->preceding & ~MM_ALLOC_BIT),
|
||||
(node->preceding & MM_ALLOC_BIT) ? 'A' : 'F');
|
||||
nodesize = SIZEOF_MM_NODE(node);
|
||||
minfo("region=%d node=%p size=%zu preceding=%u (%c)\n",
|
||||
region, node, nodesize, (unsigned int)node->preceding,
|
||||
(node->size & MM_ALLOC_BIT) ? 'A' : 'F');
|
||||
|
||||
handler(node, arg);
|
||||
|
||||
DEBUGASSERT(prev == NULL ||
|
||||
prev->size == (node->preceding & ~MM_MASK_BIT));
|
||||
SIZEOF_MM_NODE(prev) == node->preceding);
|
||||
prev = node;
|
||||
}
|
||||
|
||||
|
@ -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 *prev;
|
||||
FAR struct mm_freenode_s *next;
|
||||
size_t nodesize;
|
||||
size_t prevsize;
|
||||
|
||||
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 */
|
||||
|
||||
node = (FAR struct mm_freenode_s *)((FAR char *)mem - SIZEOF_MM_ALLOCNODE);
|
||||
nodesize = SIZEOF_MM_NODE(node);
|
||||
|
||||
/* 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 */
|
||||
|
||||
next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size);
|
||||
DEBUGASSERT((next->preceding & ~MM_MASK_BIT) == node->size);
|
||||
if ((next->preceding & MM_ALLOC_BIT) == 0)
|
||||
next = (FAR struct mm_freenode_s *)((FAR char *)node + nodesize);
|
||||
DEBUGASSERT(next->preceding == nodesize);
|
||||
if ((next->size & MM_ALLOC_BIT) == 0)
|
||||
{
|
||||
FAR struct mm_allocnode_s *andbeyond;
|
||||
size_t nextsize = SIZEOF_MM_NODE(next);
|
||||
|
||||
/* Get the node following the next node (which will
|
||||
* become the new next node). We know that we can never
|
||||
* index past the tail chunk because it is always allocated.
|
||||
*/
|
||||
|
||||
andbeyond = (FAR struct mm_allocnode_s *)
|
||||
((FAR char *)next + next->size);
|
||||
andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
|
||||
|
||||
/* Remove the next node. There must be a predecessor,
|
||||
* 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 */
|
||||
|
||||
node->size += next->size;
|
||||
andbeyond->preceding = node->size |
|
||||
(andbeyond->preceding & MM_MASK_BIT);
|
||||
nodesize += nextsize;
|
||||
node->size = nodesize | (node->size & MM_MASK_BIT);
|
||||
andbeyond->preceding = nodesize;
|
||||
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);
|
||||
DEBUGASSERT((node->preceding & ~MM_MASK_BIT) == prev->size);
|
||||
if ((prev->preceding & MM_ALLOC_BIT) == 0)
|
||||
prevsize = SIZEOF_MM_NODE(prev);
|
||||
DEBUGASSERT(node->preceding == prevsize);
|
||||
if ((prev->size & MM_ALLOC_BIT) == 0)
|
||||
{
|
||||
/* Remove the node. There must be a predecessor, but there may
|
||||
* 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 */
|
||||
|
||||
prev->size += node->size;
|
||||
next->preceding = prev->size | (next->preceding & MM_MASK_BIT);
|
||||
prevsize += nodesize;
|
||||
prev->size = prevsize | (prev->size & MM_MASK_BIT);
|
||||
next->preceding = prevsize;
|
||||
node = prev;
|
||||
}
|
||||
|
||||
|
@ -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 *)
|
||||
heapbase;
|
||||
MM_ADD_BACKTRACE(heap, heap->mm_heapstart[IDX]);
|
||||
heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
heap->mm_heapstart[IDX]->preceding = MM_ALLOC_BIT;
|
||||
heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
|
||||
node = (FAR struct mm_freenode_s *)
|
||||
(heapbase + SIZEOF_MM_ALLOCNODE);
|
||||
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;
|
||||
heap->mm_heapend[IDX] = (FAR struct mm_allocnode_s *)
|
||||
(heapend - SIZEOF_MM_ALLOCNODE);
|
||||
heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE;
|
||||
heap->mm_heapend[IDX]->preceding = node->size | MM_ALLOC_BIT;
|
||||
heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
|
||||
heap->mm_heapend[IDX]->preceding = node->size;
|
||||
MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]);
|
||||
|
||||
#undef IDX
|
||||
|
@ -39,38 +39,38 @@
|
||||
static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
||||
{
|
||||
FAR struct mallinfo *info = arg;
|
||||
size_t nodesize = SIZEOF_MM_NODE(node);
|
||||
|
||||
minfo("node=%p size=%u preceding=%u (%c)\n",
|
||||
node, (unsigned int)node->size,
|
||||
(unsigned int)(node->preceding & ~MM_ALLOC_BIT),
|
||||
(node->preceding & MM_ALLOC_BIT) ? 'A' : 'F');
|
||||
minfo("node=%p size=%zu preceding=%u (%c)\n",
|
||||
node, nodesize, (unsigned int)node->preceding,
|
||||
(node->size & MM_ALLOC_BIT) ? 'A' : 'F');
|
||||
|
||||
/* 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->uordblks += node->size;
|
||||
info->uordblks += nodesize;
|
||||
}
|
||||
else
|
||||
{
|
||||
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->size <= fnode->size);
|
||||
DEBUGASSERT(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
|
||||
DEBUGASSERT(fnode->flink == NULL ||
|
||||
fnode->flink->blink == fnode);
|
||||
DEBUGASSERT(fnode->flink == NULL ||
|
||||
fnode->flink->size == 0 ||
|
||||
fnode->flink->size >= fnode->size);
|
||||
SIZEOF_MM_NODE(fnode->flink) == 0 ||
|
||||
SIZEOF_MM_NODE(fnode->flink) >= nodesize);
|
||||
|
||||
info->ordblks++;
|
||||
info->fordblks += node->size;
|
||||
info->fordblks += nodesize;
|
||||
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 struct mallinfo_task *info = arg;
|
||||
size_t nodesize = SIZEOF_MM_NODE(node);
|
||||
|
||||
/* 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 (info->pid == -1)
|
||||
#else
|
||||
@ -92,13 +93,13 @@ static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
|
||||
#endif
|
||||
{
|
||||
info->aordblks++;
|
||||
info->uordblks += node->size;
|
||||
info->uordblks += nodesize;
|
||||
}
|
||||
}
|
||||
else if (info->pid == -2)
|
||||
{
|
||||
info->aordblks++;
|
||||
info->uordblks += node->size;
|
||||
info->uordblks += nodesize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -106,6 +106,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
{
|
||||
FAR struct mm_freenode_s *node;
|
||||
size_t alignsize;
|
||||
size_t nodesize;
|
||||
FAR void *ret = NULL;
|
||||
int ndx;
|
||||
|
||||
@ -156,11 +157,14 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
* other mm_nodelist[] entries.
|
||||
*/
|
||||
|
||||
for (node = heap->mm_nodelist[ndx].flink;
|
||||
node && node->size < alignsize;
|
||||
node = node->flink)
|
||||
for (node = heap->mm_nodelist[ndx].flink; node; node = node->flink)
|
||||
{
|
||||
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
|
||||
@ -192,13 +196,12 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
* allocation.
|
||||
*/
|
||||
|
||||
remaining = node->size - alignsize;
|
||||
remaining = nodesize - alignsize;
|
||||
if (remaining >= SIZEOF_MM_FREENODE)
|
||||
{
|
||||
/* Get a pointer to the next node in physical memory */
|
||||
|
||||
next = (FAR struct mm_freenode_s *)
|
||||
(((FAR char *)node) + node->size);
|
||||
next = (FAR struct mm_freenode_s *)(((FAR char *)node) + nodesize);
|
||||
|
||||
/* Create the remainder node */
|
||||
|
||||
@ -212,11 +215,9 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
|
||||
|
||||
node->size = alignsize;
|
||||
|
||||
/* Adjust the 'preceding' size of the (old) next node, preserving
|
||||
* the allocated flag.
|
||||
*/
|
||||
/* Adjust the 'preceding' size of the (old) next node. */
|
||||
|
||||
next->preceding = remaining | (next->preceding & MM_MASK_BIT);
|
||||
next->preceding = remaining;
|
||||
|
||||
/* 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 */
|
||||
|
||||
node->preceding |= MM_ALLOC_BIT;
|
||||
node->size |= MM_ALLOC_BIT;
|
||||
ret = (FAR void *)((FAR char *)node + SIZEOF_MM_ALLOCNODE);
|
||||
}
|
||||
|
||||
|
@ -60,7 +60,7 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
@ -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_freenode_s *prev;
|
||||
size_t precedingsize;
|
||||
|
||||
/* Mark node free */
|
||||
|
||||
node->preceding &= ~MM_MASK_BIT;
|
||||
size_t newnodesize;
|
||||
|
||||
/* 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 *)
|
||||
((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.
|
||||
*/
|
||||
|
||||
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
|
||||
* 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 */
|
||||
|
||||
newnode->size = (uintptr_t)next - (uintptr_t)newnode;
|
||||
newnode->preceding = precedingsize | MM_ALLOC_BIT;
|
||||
newnodesize = (uintptr_t)next - (uintptr_t)newnode;
|
||||
newnode->size = newnodesize | MM_ALLOC_BIT;
|
||||
newnode->preceding = precedingsize;
|
||||
|
||||
/* 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
|
||||
* 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 */
|
||||
|
||||
|
@ -54,10 +54,11 @@
|
||||
static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *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 (pid == -1)
|
||||
#else
|
||||
@ -66,7 +67,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
||||
{
|
||||
#if CONFIG_MM_BACKTRACE < 0
|
||||
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));
|
||||
#else
|
||||
# if CONFIG_MM_BACKTRACE > 0
|
||||
@ -85,7 +86,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
|
||||
# endif
|
||||
|
||||
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);
|
||||
#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;
|
||||
|
||||
DEBUGASSERT(node->size >= SIZEOF_MM_FREENODE);
|
||||
DEBUGASSERT(nodesize >= SIZEOF_MM_FREENODE);
|
||||
DEBUGASSERT(fnode->blink->flink == fnode);
|
||||
DEBUGASSERT(fnode->blink->size <= fnode->size);
|
||||
DEBUGASSERT(SIZEOF_MM_NODE(fnode->blink) <= nodesize);
|
||||
DEBUGASSERT(fnode->flink == NULL ||
|
||||
fnode->flink->blink == fnode);
|
||||
DEBUGASSERT(fnode->flink == NULL ||
|
||||
fnode->flink->size == 0 ||
|
||||
fnode->flink->size >= fnode->size);
|
||||
SIZEOF_MM_NODE(fnode->flink) == 0 ||
|
||||
SIZEOF_MM_NODE(fnode->flink) >= nodesize);
|
||||
|
||||
if (pid <= -2)
|
||||
{
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
@ -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. */
|
||||
|
||||
DEBUGVERIFY(mm_lock(heap));
|
||||
DEBUGASSERT(oldnode->preceding & MM_ALLOC_BIT);
|
||||
DEBUGASSERT(oldnode->size & MM_ALLOC_BIT);
|
||||
DEBUGASSERT(mm_heapmember(heap, oldmem));
|
||||
|
||||
/* Check if this is a request to reduce the size of the allocation. */
|
||||
|
||||
oldsize = oldnode->size;
|
||||
oldsize = SIZEOF_MM_NODE(oldnode);
|
||||
if (newsize <= oldsize)
|
||||
{
|
||||
/* 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)
|
||||
{
|
||||
mm_shrinkchunk(heap, oldnode, newsize);
|
||||
kasan_poison((FAR char *)oldnode + oldnode->size,
|
||||
oldsize - oldnode->size);
|
||||
kasan_poison((FAR char *)oldnode + SIZEOF_MM_NODE(oldnode),
|
||||
oldsize - SIZEOF_MM_NODE(oldnode));
|
||||
}
|
||||
|
||||
/* Then return the original address */
|
||||
@ -166,18 +166,17 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
|
||||
* best decision
|
||||
*/
|
||||
|
||||
next = (FAR struct mm_freenode_s *)
|
||||
((FAR char *)oldnode + oldnode->size);
|
||||
if ((next->preceding & MM_ALLOC_BIT) == 0)
|
||||
next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldsize);
|
||||
if ((next->size & MM_ALLOC_BIT) == 0)
|
||||
{
|
||||
nextsize = next->size;
|
||||
nextsize = SIZEOF_MM_NODE(next);
|
||||
}
|
||||
|
||||
prev = (FAR struct mm_freenode_s *)
|
||||
((FAR char *)oldnode - (oldnode->preceding & ~MM_MASK_BIT));
|
||||
if ((prev->preceding & MM_ALLOC_BIT) == 0)
|
||||
((FAR char *)oldnode - oldnode->preceding);
|
||||
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 */
|
||||
@ -185,6 +184,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
|
||||
if (nextsize + prevsize + oldsize >= newsize)
|
||||
{
|
||||
size_t needed = newsize - oldsize;
|
||||
size_t nodesize = oldsize;
|
||||
size_t takeprev;
|
||||
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
|
||||
*/
|
||||
|
||||
prev->size -= takeprev;
|
||||
DEBUGASSERT(prev->size >= SIZEOF_MM_FREENODE);
|
||||
newnode->size = oldsize + takeprev;
|
||||
newnode->preceding = prev->size | MM_ALLOC_BIT;
|
||||
next->preceding = newnode->size |
|
||||
(next->preceding & MM_MASK_BIT);
|
||||
prevsize -= takeprev;
|
||||
DEBUGASSERT(prevsize >= SIZEOF_MM_FREENODE);
|
||||
prev->size = prevsize;
|
||||
nodesize += takeprev;
|
||||
newnode->size = nodesize | MM_MASK_BIT;
|
||||
newnode->preceding = prevsize;
|
||||
next->preceding = nodesize;
|
||||
|
||||
/* Return the previous free node to the nodelist
|
||||
* (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) */
|
||||
|
||||
newnode->size += oldsize;
|
||||
newnode->preceding |= MM_ALLOC_BIT;
|
||||
next->preceding = newnode->size |
|
||||
(next->preceding & MM_MASK_BIT);
|
||||
nodesize += prevsize;
|
||||
newnode->size = nodesize | MM_ALLOC_BIT;
|
||||
next->preceding = nodesize;
|
||||
}
|
||||
|
||||
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 */
|
||||
|
||||
oldnode->size += takenext;
|
||||
nodesize += takenext;
|
||||
oldnode->size = nodesize | (oldnode->size & MM_MASK_BIT);
|
||||
|
||||
/* 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 *)
|
||||
((FAR char *)oldnode + oldnode->size);
|
||||
((FAR char *)oldnode + nodesize);
|
||||
newnode->size = nextsize - takenext;
|
||||
DEBUGASSERT(newnode->size >= SIZEOF_MM_FREENODE);
|
||||
newnode->preceding = oldnode->size;
|
||||
andbeyond->preceding = newnode->size |
|
||||
(andbeyond->preceding & MM_MASK_BIT);
|
||||
newnode->preceding = nodesize;
|
||||
andbeyond->preceding = newnode->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. */
|
||||
|
||||
andbeyond->preceding = oldnode->size |
|
||||
(andbeyond->preceding & MM_MASK_BIT);
|
||||
andbeyond->preceding = nodesize;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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_freenode_s *next;
|
||||
size_t nodesize = SIZEOF_MM_NODE(node);
|
||||
|
||||
DEBUGASSERT((size & MM_GRAN_MASK) == 0);
|
||||
|
||||
/* 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 */
|
||||
|
||||
if ((next->preceding & MM_ALLOC_BIT) == 0)
|
||||
if ((next->size & MM_ALLOC_BIT) == 0)
|
||||
{
|
||||
FAR struct mm_allocnode_s *andbeyond;
|
||||
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) */
|
||||
|
||||
andbeyond = (FAR struct mm_allocnode_s *)
|
||||
((FAR char *)next + next->size);
|
||||
andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
|
||||
|
||||
/* Remove the next node. There must be a predecessor, but there may
|
||||
* 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 */
|
||||
|
||||
newnode->size = next->size + node->size - size;
|
||||
newnode->size = nextsize + nodesize - size;
|
||||
newnode->preceding = size;
|
||||
node->size = size;
|
||||
andbeyond->preceding = newnode->size |
|
||||
(andbeyond->preceding & MM_MASK_BIT);
|
||||
node->size = size | (node->size & MM_MASK_BIT);
|
||||
andbeyond->preceding = newnode->size;
|
||||
|
||||
/* Add the new node to the freenodelist */
|
||||
|
||||
@ -106,7 +106,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
|
||||
* 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;
|
||||
|
||||
@ -118,11 +118,10 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
|
||||
|
||||
/* Set up the size of the new node */
|
||||
|
||||
newnode->size = node->size - size;
|
||||
newnode->size = nodesize - size;
|
||||
newnode->preceding = size;
|
||||
node->size = size;
|
||||
next->preceding = newnode->size |
|
||||
(next->preceding & MM_MASK_BIT);
|
||||
node->size = size | (node->size & MM_MASK_BIT);
|
||||
next->preceding = newnode->size;
|
||||
|
||||
/* Add the new node to the freenodelist */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user