Chinaunix首页 | 论坛 | 博客
  • 博客访问: 134472
  • 博文数量: 79
  • 博客积分: 30
  • 博客等级: 民兵
  • 技术积分: 435
  • 用 户 组: 普通用户
  • 注册时间: 2011-12-16 19:55
文章分类
文章存档

2015年(1)

2013年(1)

2012年(9)

2011年(68)

我的朋友

分类:

2011-12-16 20:43:02

9: __heap_free_area_alloc (struct heap *heap,

              struct heap_free_area *fa, size_t size)

该函数从fa所表示的空闲中,分配size大小的内存

实现如下:

extern inline size_t

__heap_free_area_alloc (struct heap *heap,

              struct heap_free_area *fa, size_t size)

{

  size_t fa_size = fa->size;

    

     //如果该空闲区剩余的内存太少。将它全部都分配出去

     //参考HEAP_MIN_FREE_AREA_SIZE的分析

  if (fa_size < size + HEAP_MIN_FREE_AREA_SIZE)

    /* There's not enough room left over in FA after allocating the block, so

       just use the whole thing, removing it from the list of free areas.  */

    {

         //faheap中删除

      __heap_delete (heap, fa);

      /* Remember that we've alloced the whole area.  */

      size = fa_size;

    }

  else

    /* Reduce size of FA to account for this allocation.  */

    fa->size = fa_size - size;

 

  return size;

}

从上面可以看出,分配内存时,只是简单的缩少了空闲区的长度。

10: __heap_alloc (heap, &size);

从堆heap中分配size字节的内存

实现如下:

void *

__heap_alloc (struct heap *heap, size_t *size)

{

  struct heap_free_area *fa;

  size_t _size = *size;

  void *mem = 0;

 

//根据HEAP_GRANULARITY 对齐 sizeof(double)

  _size = HEAP_ADJUST_SIZE (_size);

 

//如果要分配的内存比FA结构还要小,那就调整它为FA大小

  if (_size < sizeof (struct heap_free_area))

    /* Because we sometimes must use a freed block to hold a free-area node,

       we must make sure that every allocated block can hold one.  */

    _size = HEAP_ADJUST_SIZE (sizeof (struct heap_free_area));

 

  HEAP_DEBUG (heap, "before __heap_alloc");

 

  /* Look for a free area that can contain _SIZE bytes.  */

//遍历堆中的FA,找出有合适大小的空闲区

  for (fa = heap->free_areas; fa; fa = fa->next)

    if (fa->size >= _size)

      {

     /* Found one!  */

     mem = HEAP_FREE_AREA_START (fa);

     //从该空间中分得内存。这函数前面已经分析过了

     *size = __heap_free_area_alloc (heap, fa, _size);

     break;

      }

 

  HEAP_DEBUG (heap, "after __heap_alloc");

//返回地址

  return mem;

}

11__heap_free (struct heap *heap, void *mem, size_t size)

照语义上的理解是释放掉从mem开始的size大小的内存。换句话说,就是把从从mem开始的,size大小的内存段,映射回heap

它的实现如下:

struct heap_free_area *

__heap_free (struct heap *heap, void *mem, size_t size)

{

  struct heap_free_area *fa, *prev_fa;

  void *end = (char *)mem + size;

 

  HEAP_DEBUG (heap, "before __heap_free");

 

     //找第一个结束地址内存块起始地址的FA

    for (prev_fa = 0, fa = heap->free_areas; fa; prev_fa = fa, fa = fa->next)

    if (unlikely (HEAP_FREE_AREA_END (fa) >= mem))

      break;

 

  if (fa && HEAP_FREE_AREA_START (fa) <= end)

   {

         //这里是相邻的情况

      size_t fa_size = fa->size + size;

    

     //下邻

      if (HEAP_FREE_AREA_START (fa) == end)

       if (prev_fa && mem == HEAP_FREE_AREA_END (prev_fa))

        {

         //上下都相邻的情况

           fa_size += prev_fa->size;

           __heap_link_free_area_after (heap, fa, prev_fa->prev);

         }

     }

      else

     /* FA is just before the new block, expand to encompass it. */

     {

       struct heap_free_area *next_fa = fa->next;

 

       if (next_fa && end == HEAP_FREE_AREA_START (next_fa))

        {

              //上下相邻

           fa_size += next_fa->size;

           __heap_link_free_area_after (heap, next_fa, prev_fa);

           fa = next_fa;

         }

       else

         {

           fa = (struct heap_free_area *)((char *)fa + size);

            __heap_link_free_area (heap, fa, prev_fa, next_fa);

         }

     }

 

      fa->size = fa_size;

    }

  else

    /* Make the new block into a separate free-list entry.  */

//没有找到FA。那说明是在堆的末端.或者与上下都不两邻,处在一个空洞中。调用//_heap_add_free_area将内存块链接进heap.这函数参考上面相关的分析

    fa = __heap_add_free_area (heap, mem, size, prev_fa, fa);

 

  HEAP_DEBUG (heap, "after __heap_free");

 

  return fa;

}

这个函数的实现比较复杂。必须要耐着性子看

首先,先遍历heap中的FA。寻找第一个结束地起大于mem的空闲区.这里有几种情况。分别讨论如下:

1):找不到比mem大的空闲区,也就是说mem对应的内存区是在heap的末端。那就在mem对应的内存区末尾添入FA,然后加入到FA。它调用的是__heap_add_free_area()这函数我们在上面已经分析过了。如下图示:

2):找到了比mem大的空闲区fa,那也就是说,mem对应的内存是在heap的中间“空洞”中。这里有几种情况:

     1fa的起始地址要大于mem:这种情况跟第一种是一样的,只要新建一个FA插入即可。如下图示

  2mem的内存区与上下相邻的情况。如下所示:

因为有相邻的内存,所以要把合并到一个FA

阅读(565) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~