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

View File

@ -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;
};

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 *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? */

View File

@ -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);
}
}

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:
*/
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;

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 *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;
}

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 *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;
}

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 *)
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

View File

@ -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;
}
}

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;
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);
}

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 */
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;
}

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_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 */

View File

@ -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));
}
}

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. */
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;
}
}

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_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->preceding = size;
node->size = size;
next->preceding = newnode->size |
(next->preceding & MM_MASK_BIT);
newnode->size = nodesize - size;
newnode->preceding = size;
node->size = size | (node->size & MM_MASK_BIT);
next->preceding = newnode->size;
/* Add the new node to the freenodelist */