mirror of
https://github.com/apache/nuttx.git
synced 2026-06-04 14:53:47 +08:00
mm: move preceding to previous free node to reduce the overhead
Signed-off-by: wangbowen6 <wangbowen6@xiaomi.com>
This commit is contained in:
+9
-1
@@ -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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -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]);
|
||||||
|
|
||||||
|
|||||||
@@ -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
@@ -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);
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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 */
|
||||||
|
|||||||
Reference in New Issue
Block a user