前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Nuttx的realloc流程

Nuttx的realloc流程

原创
作者头像
colourfate
发布2024-02-20 17:06:30
1520
发布2024-02-20 17:06:30

1 内存管理模型

此处讨论的是nuttx的堆内存管理,其中内存管理模型如下图所示

2 通过realloc缩小内存

参考函数:nuttx/mm/mm_heap/mm_realloc.c,其中缩小内存直接进入以下分支返回,可以看到返回的仍然是oldmem,内存地址不会改变

代码语言:c
复制
FAR void *mm_realloc(FAR struct mm_heap_s *heap, FAR void *oldmem,
                     size_t size)
{
  ...
  newsize = MM_ALIGN_UP(size + SIZEOF_MM_ALLOCNODE);
  ...

  /* Check if this is a request to reduce the size of the allocation. */

  oldsize = oldnode->size;
  if (newsize <= oldsize)
    {
      /* Handle the special case where we are not going to change the size
       * of the allocation.
       */

      if (newsize < oldsize)
        {
          mm_shrinkchunk(heap, oldnode, newsize);
          kasan_poison((FAR char *)oldnode + oldnode->size,
                       oldsize - oldnode->size);
        }

      /* Then return the original address */

      mm_unlock(heap);
      MM_ADD_BACKTRACE(heap, oldnode);

      return oldmem;
    }
  ...
}

其中有个mm_shrinkchunk函数是完成缩小内存块的具体工作的,分为两种情况

  1. 缩小的内存块后面一块内存是空闲的,此时会减小当前内存块的大小,然后将多余内存合并到后面一块内存中,然后重新插入空闲链表
  2. 缩小的内存块后面一块内存已经分配,此时减小当前内存块的大小之后,将多余内存生成一个独立的内存块插入到空闲链表中

对应的代码如下:

代码语言:c
复制
void mm_shrinkchunk(FAR struct mm_heap_s *heap,
                    FAR struct mm_allocnode_s *node, size_t size)
{
  FAR struct mm_freenode_s *next;

  DEBUGASSERT((size & MM_GRAN_MASK) == 0);

  /* Get a reference to the next node */
  // 得到相邻后面一块内存描述符
  next = (FAR struct mm_freenode_s *)((FAR char *)node + node->size);

  /* Check if it is free */
  // 后面一块内存空闲
  if ((next->preceding & MM_ALLOC_BIT) == 0)
    {
      FAR struct mm_allocnode_s *andbeyond;
      FAR struct mm_freenode_s *newnode;

      /* Get the chunk next the next node (which could be the tail chunk) */

      andbeyond = (FAR struct mm_allocnode_s *)
                  ((FAR char *)next + next->size);

      /* Remove the next node.  There must be a predecessor, but there may
       * not be a successor node.
       */
      // 将下一个结点移除
      DEBUGASSERT(next->blink);
      next->blink->flink = next->flink;
      if (next->flink)
        {
          next->flink->blink = next->blink;
        }

      /* Create a new chunk that will hold both the next chunk and the
       * tailing memory from the aligned chunk.
       */
      // 创建一个新的结点
      newnode = (FAR struct mm_freenode_s *)((FAR char *)node + size);

      /* Set up the size of the new node */
      // 合并后的大小
      newnode->size        = next->size + node->size - size;
      newnode->preceding   = size;
      node->size           = size;
      andbeyond->preceding = newnode->size |
                             (andbeyond->preceding & MM_MASK_BIT);

      /* Add the new node to the freenodelist */
      // 新结点插入到空闲队列
      mm_addfreechunk(heap, newnode);
    }

  /* The next chunk is allocated.  Try to free the end portion at the end
   * chunk to be shrunk.
   */
  // 后面内存不空闲
  else if (node->size >= size + SIZEOF_MM_FREENODE)
    {
      FAR struct mm_freenode_s *newnode;

      /* Create a new chunk that will hold both the next chunk and the
       * tailing memory from the aligned chunk.
       */
      // 创建新结点
      newnode = (FAR struct mm_freenode_s *)((FAR char *)node + size);

      /* 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);

      /* Add the new node to the freenodelist */
      // 插入到空闲队列
      mm_addfreechunk(heap, newnode);
    }
}

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 内存管理模型
  • 2 通过realloc缩小内存
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档