mm: add macro to judge if node/prenode is free

Signed-off-by: Xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
Xuxingliang 2023-09-06 12:30:24 +08:00 committed by Xiang Xiao
parent c9f33b7ee5
commit b9e59ad0a7
13 changed files with 41 additions and 29 deletions

View file

@ -149,6 +149,14 @@
#define MM_SIZEOF_NODE(node) ((node)->size & (~MM_MASK_BIT))
/* Check if node/prenode is free */
#define MM_NODE_IS_ALLOC(node) ((node->size & MM_ALLOC_BIT) != 0)
#define MM_NODE_IS_FREE(node) ((node->size & MM_ALLOC_BIT) == 0)
#define MM_PREVNODE_IS_ALLOC(node) ((node->size & MM_PREVFREE_BIT) == 0)
#define MM_PREVNODE_IS_FREE(node) ((node->size & MM_PREVFREE_BIT) != 0)
/****************************************************************************
* Public Types
****************************************************************************/

View file

@ -52,7 +52,7 @@ void mm_addfreechunk(FAR struct mm_heap_s *heap,
int ndx;
DEBUGASSERT(nodesize >= MM_MIN_CHUNK);
DEBUGASSERT((node->size & MM_ALLOC_BIT) == 0);
DEBUGASSERT(MM_NODE_IS_FREE(node));
/* Convert the size to a nodelist index */

View file

@ -42,7 +42,7 @@ static void checkcorruption_handler(FAR struct mm_allocnode_s *node,
{
size_t nodesize = MM_SIZEOF_NODE(node);
if ((node->size & MM_ALLOC_BIT) != 0)
if (MM_NODE_IS_ALLOC(node))
{
assert(nodesize >= MM_SIZEOF_ALLOCNODE);
}

View file

@ -96,7 +96,7 @@ void mm_extend(FAR struct mm_heap_s *heap, FAR void *mem, size_t size,
/* The old node should already be marked as allocated */
DEBUGASSERT((oldnode->size & MM_ALLOC_BIT) != 0);
DEBUGASSERT(MM_NODE_IS_ALLOC(oldnode));
/* Get and initialize the new terminal node in the heap */

View file

@ -81,12 +81,12 @@ void mm_foreach(FAR struct mm_heap_s *heap, mm_node_handler_t handler,
nodesize = MM_SIZEOF_NODE(node);
minfo("region=%d node=%p size=%zu preceding=%u (%c %c)\n",
region, node, nodesize, (unsigned int)node->preceding,
(node->size & MM_PREVFREE_BIT) ? 'F' : 'A',
(node->size & MM_ALLOC_BIT) ? 'A' : 'F');
MM_PREVNODE_IS_FREE(node) ? 'F' : 'A',
MM_NODE_IS_ALLOC(node) ? 'A' : 'F');
handler(node, arg);
DEBUGASSERT((node->size & MM_PREVFREE_BIT) == 0 ||
DEBUGASSERT(MM_PREVNODE_IS_ALLOC(node) ||
MM_SIZEOF_NODE(prev) == node->preceding);
prev = node;
}

View file

@ -117,15 +117,15 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
/* Sanity check against double-frees */
DEBUGASSERT(node->size & MM_ALLOC_BIT);
DEBUGASSERT(MM_NODE_IS_ALLOC(node));
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 + nodesize);
DEBUGASSERT((next->size & MM_PREVFREE_BIT) == 0);
if ((next->size & MM_ALLOC_BIT) == 0)
DEBUGASSERT(MM_PREVNODE_IS_ALLOC(next));
if (MM_NODE_IS_FREE(next))
{
FAR struct mm_allocnode_s *andbeyond;
size_t nextsize = MM_SIZEOF_NODE(next);
@ -136,8 +136,8 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
*/
andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
DEBUGASSERT((andbeyond->size & MM_PREVFREE_BIT) != 0 &&
andbeyond->preceding == nextsize);
DEBUGASSERT(MM_PREVNODE_IS_FREE(andbeyond) &&
andbeyond->preceding == nextsize);
/* Remove the next node. There must be a predecessor,
* but there may not be a successor node.
@ -167,13 +167,12 @@ void mm_free(FAR struct mm_heap_s *heap, FAR void *mem)
* it with this node
*/
if ((node->size & MM_PREVFREE_BIT) != 0)
if (MM_PREVNODE_IS_FREE(node))
{
prev = (FAR struct mm_freenode_s *)
((FAR char *)node - node->preceding);
prevsize = MM_SIZEOF_NODE(prev);
DEBUGASSERT((prev->size & MM_ALLOC_BIT) == 0 &&
node->preceding == prevsize);
DEBUGASSERT(MM_NODE_IS_FREE(prev) && node->preceding == prevsize);
/* Remove the node. There must be a predecessor, but there may
* not be a successor node.

View file

@ -52,11 +52,11 @@ static void mallinfo_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
minfo("node=%p size=%zu preceding=%u (%c)\n",
node, nodesize, (unsigned int)node->preceding,
(node->size & MM_ALLOC_BIT) ? 'A' : 'F');
MM_NODE_IS_ALLOC(node) ? 'A' : 'F');
/* Check if the node corresponds to an allocated memory chunk */
if ((node->size & MM_ALLOC_BIT) != 0)
if (MM_NODE_IS_ALLOC(node))
{
DEBUGASSERT(nodesize >= MM_SIZEOF_ALLOCNODE);
info->aordblks++;
@ -94,7 +94,7 @@ static void mallinfo_task_handler(FAR struct mm_allocnode_s *node,
/* Check if the node corresponds to an allocated memory chunk */
if ((node->size & MM_ALLOC_BIT) != 0)
if (MM_NODE_IS_ALLOC(node))
{
DEBUGASSERT(nodesize >= MM_SIZEOF_ALLOCNODE);
#if CONFIG_MM_BACKTRACE < 0

View file

@ -204,8 +204,13 @@ FAR void *mm_malloc(FAR struct mm_heap_s *heap, size_t size)
/* 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 &&
/* Node next must be alloced, otherwise it should be merged.
* Its prenode(the founded node) must be free and preceding should
* match with nodesize.
*/
DEBUGASSERT(MM_NODE_IS_ALLOC(next) && MM_PREVNODE_IS_FREE(next) &&
next->preceding == nodesize);
/* Check if we have to split the free node into one of the allocated

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->size & MM_ALLOC_BIT);
DEBUGASSERT(MM_NODE_IS_ALLOC(node));
return MM_SIZEOF_NODE(node) - MM_ALLOCNODE_OVERHEAD;
}

View file

@ -194,7 +194,7 @@ FAR void *mm_memalign(FAR struct mm_heap_s *heap, size_t alignment,
* set up the node size.
*/
if ((node->size & MM_PREVFREE_BIT) != 0)
if (MM_PREVNODE_IS_FREE(node))
{
FAR struct mm_freenode_s *prev =
(FAR struct mm_freenode_s *)((FAR char *)node - node->preceding);

View file

@ -55,7 +55,7 @@ static void memdump_handler(FAR struct mm_allocnode_s *node, FAR void *arg)
FAR const struct mm_memdump_s *dump = arg;
size_t nodesize = MM_SIZEOF_NODE(node);
if ((node->size & MM_ALLOC_BIT) != 0)
if (MM_NODE_IS_ALLOC(node))
{
DEBUGASSERT(nodesize >= MM_SIZEOF_ALLOCNODE);
#if CONFIG_MM_BACKTRACE < 0

View file

@ -130,7 +130,7 @@ 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->size & MM_ALLOC_BIT);
DEBUGASSERT(MM_NODE_IS_ALLOC(oldnode));
/* Check if this is a request to reduce the size of the allocation. */
@ -162,17 +162,17 @@ FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
*/
next = (FAR struct mm_freenode_s *)((FAR char *)oldnode + oldsize);
if ((next->size & MM_ALLOC_BIT) == 0)
if (MM_NODE_IS_FREE(next))
{
DEBUGASSERT((next->size & MM_PREVFREE_BIT) == 0);
DEBUGASSERT(MM_PREVNODE_IS_ALLOC(next));
nextsize = MM_SIZEOF_NODE(next);
}
if ((oldnode->size & MM_PREVFREE_BIT) != 0)
if (MM_PREVNODE_IS_FREE(oldnode))
{
prev = (FAR struct mm_freenode_s *)
((FAR char *)oldnode - oldnode->preceding);
DEBUGASSERT((prev->size & MM_ALLOC_BIT) == 0);
DEBUGASSERT(MM_NODE_IS_FREE(prev));
prevsize = MM_SIZEOF_NODE(prev);
}

View file

@ -63,7 +63,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
/* Check if it is free */
if ((next->size & MM_ALLOC_BIT) == 0)
if (MM_NODE_IS_FREE(next))
{
FAR struct mm_allocnode_s *andbeyond;
FAR struct mm_freenode_s *newnode;
@ -72,7 +72,7 @@ void mm_shrinkchunk(FAR struct mm_heap_s *heap,
/* Get the chunk next the next node (which could be the tail chunk) */
andbeyond = (FAR struct mm_allocnode_s *)((FAR char *)next + nextsize);
DEBUGASSERT((andbeyond->size & MM_PREVFREE_BIT) != 0);
DEBUGASSERT(MM_PREVNODE_IS_FREE(andbeyond));
/* Remove the next node. There must be a predecessor, but there may
* not be a successor node.