mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 13:18:50 +08:00
mm: add macro to judge if node/prenode is free
Signed-off-by: Xuxingliang <xuxingliang@xiaomi.com>
This commit is contained in:
parent
c9f33b7ee5
commit
b9e59ad0a7
13 changed files with 41 additions and 29 deletions
|
@ -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
|
||||
****************************************************************************/
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Reference in a new issue