mm: move preceding to previous free node to reduce the overhead

Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
wangbowen6
2022-12-22 16:02:42 +08:00
committed by Xiang Xiao
parent 723c6e52e2
commit b1948a1631
11 changed files with 105 additions and 70 deletions
+9 -1
View File
@@ -119,7 +119,8 @@
*/ */
#define MM_ALLOC_BIT 0x1 #define MM_ALLOC_BIT 0x1
#define MM_MASK_BIT MM_ALLOC_BIT #define MM_PREVFREE_BIT 0x2
#define MM_MASK_BIT (MM_ALLOC_BIT | MM_PREVFREE_BIT)
#ifdef CONFIG_MM_SMALL #ifdef CONFIG_MM_SMALL
# define MMSIZE_MAX UINT16_MAX # define MMSIZE_MAX UINT16_MAX
#else #else
@@ -130,6 +131,13 @@
#define SIZEOF_MM_ALLOCNODE sizeof(struct mm_allocnode_s) #define SIZEOF_MM_ALLOCNODE sizeof(struct mm_allocnode_s)
/* What is the overhead of the allocnode
* Remove the space of preceding field since it locates at the end of the
* previous freenode
*/
#define OVERHEAD_MM_ALLOCNODE (SIZEOF_MM_ALLOCNODE - sizeof(mmsize_t))
/* What is the size of the freenode? */ /* What is the size of the freenode? */
#define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s) #define SIZEOF_MM_FREENODE sizeof(struct mm_freenode_s)
-1
View File
@@ -103,7 +103,6 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
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 | MM_ALLOC_BIT; newnode->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT;
newnode->preceding = size;
heap->mm_heapend[region] = newnode; heap->mm_heapend[region] = newnode;
+3 -2
View File
@@ -79,13 +79,14 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler,
node = (FAR struct mm_allocnode_s *)((FAR char *)node + nodesize)) node = (FAR struct mm_allocnode_s *)((FAR char *)node + nodesize))
{ {
nodesize = SIZEOF_MM_NODE(node); nodesize = SIZEOF_MM_NODE(node);
minfo("region=%d node=%p size=%zu preceding=%u (%c)\n", minfo("region=%d node=%p size=%zu preceding=%u (%c %c)\n",
region, node, nodesize, (unsigned int)node->preceding, region, node, nodesize, (unsigned int)node->preceding,
(node->size & MM_PREVFREE_BIT) ? 'F' : 'A',
(node->size & MM_ALLOC_BIT) ? 'A' : 'F'); (node->size & MM_ALLOC_BIT) ? 'A' : 'F');
handler(node, arg); handler(node, arg);
DEBUGASSERT(prev == NULL || DEBUGASSERT((node->size & MM_PREVFREE_BIT) == 0 ||
SIZEOF_MM_NODE(prev) == node->preceding); SIZEOF_MM_NODE(prev) == node->preceding);
prev = node; prev = node;
} }
+15 -5
View File
@@ -120,7 +120,7 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
/* 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 + nodesize); next = (FAR struct mm_freenode_s *)((FAR char *)node + nodesize);
DEBUGASSERT(next->preceding == nodesize); DEBUGASSERT((next->size & MM_PREVFREE_BIT) == 0);
if ((next->size & MM_ALLOC_BIT) == 0) if ((next->size & MM_ALLOC_BIT) == 0)
{ {
FAR struct mm_allocnode_s *andbeyond; FAR struct mm_allocnode_s *andbeyond;
@@ -132,6 +132,8 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
*/ */
andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize); andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
DEBUGASSERT((andbeyond->size & MM_PREVFREE_BIT) != 0 &&
andbeyond->preceding == nextsize);
/* 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.
@@ -151,16 +153,24 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
andbeyond->preceding = nodesize; andbeyond->preceding = nodesize;
next = (FAR struct mm_freenode_s *)andbeyond; next = (FAR struct mm_freenode_s *)andbeyond;
} }
else
{
next->size |= MM_PREVFREE_BIT;
next->preceding = nodesize;
}
/* Check if the preceding node is also free and, if so, merge /* Check if the preceding node is also free and, if so, merge
* it with this node * it with this node
*/ */
prev = (FAR struct mm_freenode_s *)((FAR char *)node - node->preceding); if ((node->size & MM_PREVFREE_BIT) != 0)
prevsize = SIZEOF_MM_NODE(prev);
DEBUGASSERT(node->preceding == prevsize);
if ((prev->size & MM_ALLOC_BIT) == 0)
{ {
prev = (FAR struct mm_freenode_s *)
((FAR char *)node - node->preceding);
prevsize = SIZEOF_MM_NODE(prev);
DEBUGASSERT((prev->size & MM_ALLOC_BIT) == 0 &&
node->preceding == prevsize);
/* 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.
*/ */
+4 -5
View File
@@ -134,18 +134,17 @@ void mm_addregion(FAR struct mm_heap_s *heap, FAR void *heapstart,
* all available memory. * all available memory.
*/ */
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 | MM_ALLOC_BIT; heap->mm_heapstart[IDX]->size = SIZEOF_MM_ALLOCNODE | 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);
node->size = heapsize - 2*SIZEOF_MM_ALLOCNODE; node->size = heapsize - 2 * 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 | MM_ALLOC_BIT; heap->mm_heapend[IDX]->size = SIZEOF_MM_ALLOCNODE | MM_ALLOC_BIT |
MM_PREVFREE_BIT;
heap->mm_heapend[IDX]->preceding = node->size; heap->mm_heapend[IDX]->preceding = node->size;
MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]); MM_ADD_BACKTRACE(heap, heap->mm_heapend[IDX]);
+9 -1
View File
@@ -129,7 +129,15 @@ int mm_mallinfo(FAR struct mm_heap_s *heap, FAR struct mallinfo *info)
mm_foreach(heap, mallinfo_handler, info); mm_foreach(heap, mallinfo_handler, info);
info->arena = heap->mm_heapsize; info->arena = heap->mm_heapsize;
info->uordblks += region * SIZEOF_MM_ALLOCNODE; /* account for the tail node */
/* Account for the heap->mm_heapend[region] node overhead and the
* heap->mm_heapstart[region]->preceding:
* heap->mm_heapend[region] overhead size = OVERHEAD_MM_ALLOCNODE
* heap->mm_heapstart[region]->preceding size = sizeof(mmsize_t)
* and SIZEOF_MM_ALLOCNODE = OVERHEAD_MM_ALLOCNODE + sizeof(mmsize_t).
*/
info->uordblks += region * SIZEOF_MM_ALLOCNODE;
DEBUGASSERT((size_t)info->uordblks + info->fordblks == heap->mm_heapsize); DEBUGASSERT((size_t)info->uordblks + info->fordblks == heap->mm_heapsize);
+18 -8
View File
@@ -133,7 +133,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
* (2) to make sure that it is an even multiple of our granule size. * (2) to make sure that it is an even multiple of our granule size.
*/ */
alignsize = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE); alignsize = MM_ALIGN_UP(size + OVERHEAD_MM_ALLOCNODE);
if (alignsize < size) if (alignsize < size)
{ {
/* There must have been an integer overflow */ /* There must have been an integer overflow */
@@ -189,6 +189,13 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
node->flink->blink = node->blink; node->flink->blink = node->blink;
} }
/* Get a pointer to the next node in physical memory */
next = (FAR struct mm_freenode_s *)(((FAR char *)node) + nodesize);
DEBUGASSERT((next->size & MM_ALLOC_BIT) != 0 &&
(next->size & MM_PREVFREE_BIT) != 0 &&
next->preceding == nodesize);
/* Check if we have to split the free node into one of the allocated /* Check if we have to split the free node into one of the allocated
* size and another smaller freenode. In some cases, the remaining * size and another smaller freenode. In some cases, the remaining
* bytes can be smaller (they may be SIZEOF_MM_ALLOCNODE). In that * bytes can be smaller (they may be SIZEOF_MM_ALLOCNODE). In that
@@ -199,21 +206,16 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
remaining = nodesize - alignsize; remaining = nodesize - alignsize;
if (remaining >= SIZEOF_MM_FREENODE) if (remaining >= SIZEOF_MM_FREENODE)
{ {
/* Get a pointer to the next node in physical memory */
next = (FAR struct mm_freenode_s *)(((FAR char *)node) + nodesize);
/* Create the remainder node */ /* Create the remainder node */
remainder = (FAR struct mm_freenode_s *) remainder = (FAR struct mm_freenode_s *)
(((FAR char *)node) + alignsize); (((FAR char *)node) + alignsize);
remainder->size = remaining; remainder->size = remaining;
remainder->preceding = alignsize;
/* Adjust the size of the node under consideration */ /* Adjust the size of the node under consideration */
node->size = alignsize; node->size = alignsize | (node->size & MM_MASK_BIT);
/* Adjust the 'preceding' size of the (old) next node. */ /* Adjust the 'preceding' size of the (old) next node. */
@@ -223,6 +225,14 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
mm_addfreechunk(heap, remainder); mm_addfreechunk(heap, remainder);
} }
else
{
/* Previous physical memory node is alloced, so clear the previous
* free bit in next->size.
*/
next->size &= ~MM_PREVFREE_BIT;
}
/* Handle the case of an exact size match */ /* Handle the case of an exact size match */
@@ -238,7 +248,7 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
MM_ADD_BACKTRACE(heap, node); MM_ADD_BACKTRACE(heap, node);
kasan_unpoison(ret, mm_malloc_size(heap, ret)); kasan_unpoison(ret, mm_malloc_size(heap, ret));
#ifdef CONFIG_MM_FILL_ALLOCATIONS #ifdef CONFIG_MM_FILL_ALLOCATIONS
memset(ret, 0xaa, alignsize - SIZEOF_MM_ALLOCNODE); memset(ret, 0xaa, alignsize - OVERHEAD_MM_ALLOCNODE);
#endif #endif
#ifdef CONFIG_DEBUG_MM #ifdef CONFIG_DEBUG_MM
minfo("Allocated %p, size %zu\n", ret, alignsize); minfo("Allocated %p, size %zu\n", ret, alignsize);
+1 -1
View File
@@ -62,5 +62,5 @@ size_t mm_malloc_size(FAR struct mm_heap_s *heap, FAR void *mem)
DEBUGASSERT(node->size & MM_ALLOC_BIT); DEBUGASSERT(node->size & MM_ALLOC_BIT);
return SIZEOF_MM_NODE(node) - SIZEOF_MM_ALLOCNODE; return SIZEOF_MM_NODE(node) - OVERHEAD_MM_ALLOCNODE;
} }
+13 -13
View File
@@ -146,7 +146,6 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
{ {
FAR struct mm_allocnode_s *newnode; FAR struct mm_allocnode_s *newnode;
FAR struct mm_allocnode_s *next; FAR struct mm_allocnode_s *next;
FAR struct mm_freenode_s *prev;
size_t precedingsize; size_t precedingsize;
size_t newnodesize; size_t newnodesize;
@@ -154,8 +153,6 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
next = (FAR struct mm_allocnode_s *) next = (FAR struct mm_allocnode_s *)
((FAR char *)node + SIZEOF_MM_NODE(node)); ((FAR char *)node + SIZEOF_MM_NODE(node));
prev = (FAR struct mm_freenode_s *)
((FAR char *)node - node->preceding);
/* Make sure that there is space to convert the preceding /* Make sure that there is space to convert the preceding
* mm_allocnode_s into an mm_freenode_s. I think that this should * mm_allocnode_s into an mm_freenode_s. I think that this should
@@ -193,8 +190,11 @@ 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->size & MM_ALLOC_BIT) == 0) if ((node->size & MM_PREVFREE_BIT) != 0)
{ {
FAR struct mm_freenode_s *prev =
(FAR struct mm_freenode_s *)((FAR char *)node - node->preceding);
/* 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.
*/ */
@@ -206,7 +206,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
prev->flink->blink = prev->blink; prev->flink->blink = prev->blink;
} }
precedingsize += prev->size; precedingsize += SIZEOF_MM_NODE(prev);
node = (FAR struct mm_allocnode_s *)prev; node = (FAR struct mm_allocnode_s *)prev;
} }
@@ -215,18 +215,18 @@ 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 */
newnodesize = (uintptr_t)next - (uintptr_t)newnode; newnodesize = (uintptr_t)next - (uintptr_t)newnode;
newnode->size = newnodesize | MM_ALLOC_BIT; newnode->size = newnodesize | MM_ALLOC_BIT | MM_PREVFREE_BIT;
newnode->preceding = precedingsize; newnode->preceding = precedingsize;
/* Fix the preceding size of the next node */ /* Clear the previous free bit of the next node */
next->preceding = newnodesize; next->size &= ~MM_PREVFREE_BIT;
/* 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 OVERHEAD_MM_ALLOCNODE.
*/ */
allocsize = newnodesize - SIZEOF_MM_ALLOCNODE; allocsize = newnodesize - OVERHEAD_MM_ALLOCNODE;
/* Add the original, newly freed node to the free nodelist */ /* Add the original, newly freed node to the free nodelist */
@@ -240,16 +240,16 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
} }
/* Check if there is free space at the end of the aligned chunk. Convert /* Check if there is free space at the end of the aligned chunk. Convert
* malloc-compatible chunk size to include SIZEOF_MM_ALLOCNODE as needed * malloc-compatible chunk size to include OVERHEAD_MM_ALLOCNODE as needed
* for mm_shrinkchunk. * for mm_shrinkchunk.
*/ */
size = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE); size = MM_ALIGN_UP(size + OVERHEAD_MM_ALLOCNODE);
if (allocsize > size) if (allocsize > size)
{ {
/* Shrink the chunk by that much -- remember, mm_shrinkchunk wants /* Shrink the chunk by that much -- remember, mm_shrinkchunk wants
* internal chunk sizes that include SIZEOF_MM_ALLOCNODE. * internal chunk sizes that include OVERHEAD_MM_ALLOCNODE.
*/ */
mm_shrinkchunk(heap, node, size); mm_shrinkchunk(heap, node, size);
+16 -16
View File
@@ -71,7 +71,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
size_t size) size_t size)
{ {
FAR struct mm_allocnode_s *oldnode; FAR struct mm_allocnode_s *oldnode;
FAR struct mm_freenode_s *prev; FAR struct mm_freenode_s *prev = NULL;
FAR struct mm_freenode_s *next; FAR struct mm_freenode_s *next;
size_t newsize; size_t newsize;
size_t oldsize; size_t oldsize;
@@ -117,7 +117,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
* (2) to make sure that it is an even multiple of our granule size. * (2) to make sure that it is an even multiple of our granule size.
*/ */
newsize = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE); newsize = MM_ALIGN_UP(size + OVERHEAD_MM_ALLOCNODE);
if (newsize < size) if (newsize < size)
{ {
/* There must have been an integer overflow */ /* There must have been an integer overflow */
@@ -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 + SIZEOF_MM_NODE(oldnode), kasan_poison((FAR char *)oldnode + SIZEOF_MM_NODE(oldnode) +
oldsize - SIZEOF_MM_NODE(oldnode)); sizeof(mmsize_t), oldsize - SIZEOF_MM_NODE(oldnode));
} }
/* Then return the original address */ /* Then return the original address */
@@ -169,13 +169,15 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldsize); next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldsize);
if ((next->size & MM_ALLOC_BIT) == 0) if ((next->size & MM_ALLOC_BIT) == 0)
{ {
DEBUGASSERT((next->size & MM_PREVFREE_BIT) == 0);
nextsize = SIZEOF_MM_NODE(next); nextsize = SIZEOF_MM_NODE(next);
} }
if ((oldnode->size & MM_PREVFREE_BIT) != 0)
{
prev = (FAR struct mm_freenode_s *) prev = (FAR struct mm_freenode_s *)
((FAR char *)oldnode - oldnode->preceding); ((FAR char *)oldnode - oldnode->preceding);
if ((prev->size & MM_ALLOC_BIT) == 0) DEBUGASSERT((prev->size & MM_ALLOC_BIT) == 0);
{
prevsize = SIZEOF_MM_NODE(prev); prevsize = SIZEOF_MM_NODE(prev);
} }
@@ -251,7 +253,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
* there may not be a successor node. * there may not be a successor node.
*/ */
DEBUGASSERT(prev->blink); DEBUGASSERT(prev && prev->blink);
prev->blink->flink = prev->flink; prev->blink->flink = prev->flink;
if (prev->flink) if (prev->flink)
{ {
@@ -273,11 +275,10 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
prevsize -= takeprev; prevsize -= takeprev;
DEBUGASSERT(prevsize >= SIZEOF_MM_FREENODE); DEBUGASSERT(prevsize >= SIZEOF_MM_FREENODE);
prev->size = prevsize; prev->size = prevsize | (prev->size & MM_MASK_BIT);
nodesize += takeprev; nodesize += takeprev;
newnode->size = nodesize | MM_MASK_BIT; newnode->size = nodesize | MM_ALLOC_BIT | MM_PREVFREE_BIT;
newnode->preceding = prevsize; 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)
@@ -290,8 +291,8 @@ 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) */
nodesize += prevsize; nodesize += prevsize;
newnode->size = nodesize | MM_ALLOC_BIT; newnode->size = nodesize | MM_ALLOC_BIT |
next->preceding = nodesize; (newnode->size & MM_MASK_BIT);
} }
newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE); newmem = (FAR void *)((FAR char *)newnode + SIZEOF_MM_ALLOCNODE);
@@ -343,7 +344,6 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
((FAR char *)oldnode + nodesize); ((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 = nodesize;
andbeyond->preceding = newnode->size; andbeyond->preceding = newnode->size;
/* 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,7 +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 = nodesize; andbeyond->size &= ~MM_PREVFREE_BIT;
} }
} }
@@ -368,7 +368,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
* should be safe for this. * should be safe for this.
*/ */
memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE); memcpy(newmem, oldmem, oldsize - OVERHEAD_MM_ALLOCNODE);
} }
return newmem; return newmem;
@@ -388,7 +388,7 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
newmem = mm_malloc(heap, size); newmem = mm_malloc(heap, size);
if (newmem) if (newmem)
{ {
memcpy(newmem, oldmem, oldsize - SIZEOF_MM_ALLOCNODE); memcpy(newmem, oldmem, oldsize - OVERHEAD_MM_ALLOCNODE);
mm_free(heap, oldmem); mm_free(heap, oldmem);
} }
+2 -2
View File
@@ -72,6 +72,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
/* 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 *)((FAR char *)next + nextsize); andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
DEBUGASSERT((andbeyond->size & MM_PREVFREE_BIT) != 0);
/* 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.
@@ -93,7 +94,6 @@ 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 = nextsize + nodesize - size; newnode->size = nextsize + nodesize - size;
newnode->preceding = size;
node->size = size | (node->size & MM_MASK_BIT); node->size = size | (node->size & MM_MASK_BIT);
andbeyond->preceding = newnode->size; andbeyond->preceding = newnode->size;
@@ -119,8 +119,8 @@ 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 = nodesize - size; newnode->size = nodesize - size;
newnode->preceding = size;
node->size = size | (node->size & MM_MASK_BIT); node->size = size | (node->size & MM_MASK_BIT);
next->size |= MM_PREVFREE_BIT;
next->preceding = newnode->size; next->preceding = newnode->size;
/* Add the new node to the freenodelist */ /* Add the new node to the freenodelist */