This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit 723c6e52e2da34ffde9ce17cbd004ae3a0397cd7 Author: wangbowen6 <wangbow...@xiaomi.com> AuthorDate: Thu Dec 15 19:55:16 2022 +0800 mm: reorder the preceding and size and move MM_ALLOC_BIT to size Signed-off-by: wangbowen6 <wangbow...@xiaomi.com> --- mm/mm_heap/mm.h | 12 ++++++--- mm/mm_heap/mm_addfreechunk.c | 9 ++++--- mm/mm_heap/mm_checkcorruption.c | 14 ++++++----- mm/mm_heap/mm_extend.c | 8 +++--- mm/mm_heap/mm_foreach.c | 14 +++++------ mm/mm_heap/mm_free.c | 33 ++++++++++++++----------- mm/mm_heap/mm_initialize.c | 7 +++--- mm/mm_heap/mm_mallinfo.c | 35 +++++++++++++------------- mm/mm_heap/mm_malloc.c | 23 ++++++++--------- mm/mm_heap/mm_malloc_size.c | 4 +-- mm/mm_heap/mm_memalign.c | 19 +++++++------- mm/mm_heap/mm_memdump.c | 19 +++++++------- mm/mm_heap/mm_realloc.c | 55 ++++++++++++++++++++--------------------- mm/mm_heap/mm_shrinkchunk.c | 27 ++++++++++---------- 14 files changed, 145 insertions(+), 134 deletions(-) diff --git a/mm/mm_heap/mm.h b/mm/mm_heap/mm.h index 958b3f3008..764156d826 100644 --- a/mm/mm_heap/mm.h +++ b/mm/mm_heap/mm.h @@ -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; }; diff --git a/mm/mm_heap/mm_addfreechunk.c b/mm/mm_heap/mm_addfreechunk.c index 77f8f2e4f7..335451fff7 100644 --- a/mm/mm_heap/mm_addfreechunk.c +++ b/mm/mm_heap/mm_addfreechunk.c @@ -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? */ diff --git a/mm/mm_heap/mm_checkcorruption.c b/mm/mm_heap/mm_checkcorruption.c index 666d1b675d..9e82833e53 100644 --- a/mm/mm_heap/mm_checkcorruption.c +++ b/mm/mm_heap/mm_checkcorruption.c @@ -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); } } diff --git a/mm/mm_heap/mm_extend.c b/mm/mm_heap/mm_extend.c index 8ff2ddec0b..94c2392a0c 100644 --- a/mm/mm_heap/mm_extend.c +++ b/mm/mm_heap/mm_extend.c @@ -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; diff --git a/mm/mm_heap/mm_foreach.c b/mm/mm_heap/mm_foreach.c index 827fb776c9..58daef0cb8 100644 --- a/mm/mm_heap/mm_foreach.c +++ b/mm/mm_heap/mm_foreach.c @@ -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; } diff --git a/mm/mm_heap/mm_free.c b/mm/mm_heap/mm_free.c index cef44775a2..6ca89dd314 100644 --- a/mm/mm_heap/mm_free.c +++ b/mm/mm_heap/mm_free.c @@ -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; } diff --git a/mm/mm_heap/mm_initialize.c b/mm/mm_heap/mm_initialize.c index 830bf15389..ebcffa79c6 100644 --- a/mm/mm_heap/mm_initialize.c +++ b/mm/mm_heap/mm_initialize.c @@ -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 diff --git a/mm/mm_heap/mm_mallinfo.c b/mm/mm_heap/mm_mallinfo.c index 0c51df59f3..0e6ee6eda6 100644 --- a/mm/mm_heap/mm_mallinfo.c +++ b/mm/mm_heap/mm_mallinfo.c @@ -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; } } diff --git a/mm/mm_heap/mm_malloc.c b/mm/mm_heap/mm_malloc.c index e2f57fb83c..22919c1f43 100644 --- a/mm/mm_heap/mm_malloc.c +++ b/mm/mm_heap/mm_malloc.c @@ -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); } diff --git a/mm/mm_heap/mm_malloc_size.c b/mm/mm_heap/mm_malloc_size.c index 96eb27c4e6..b70ec55c7b 100644 --- a/mm/mm_heap/mm_malloc_size.c +++ b/mm/mm_heap/mm_malloc_size.c @@ -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; } diff --git a/mm/mm_heap/mm_memalign.c b/mm/mm_heap/mm_memalign.c index 27933c200f..db73e85144 100644 --- a/mm/mm_heap/mm_memalign.c +++ b/mm/mm_heap/mm_memalign.c @@ -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 */ diff --git a/mm/mm_heap/mm_memdump.c b/mm/mm_heap/mm_memdump.c index f6774bdc50..a0ad5c5c7f 100644 --- a/mm/mm_heap/mm_memdump.c +++ b/mm/mm_heap/mm_memdump.c @@ -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)); } } diff --git a/mm/mm_heap/mm_realloc.c b/mm/mm_heap/mm_realloc.c index 85239783b4..a9e3fdc150 100644 --- a/mm/mm_heap/mm_realloc.c +++ b/mm/mm_heap/mm_realloc.c @@ -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; } } diff --git a/mm/mm_heap/mm_shrinkchunk.c b/mm/mm_heap/mm_shrinkchunk.c index 42c87e0bad..7d950b8d63 100644 --- a/mm/mm_heap/mm_shrinkchunk.c +++ b/mm/mm_heap/mm_shrinkchunk.c @@ -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 */