Chinaunix首页 | 论坛 | 博客
  • 博客访问: 68167
  • 博文数量: 19
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 239
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-08 15:35
文章分类

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 15:56:23

下面我们开始分析三个malloc函数分别是DevMemSysAllocatorMmapSysAllocator,以及SbrkSysAllocator./src/system-alloc.cc)。

首先分析SbrkSysAllocator./src/system-alloc.cc

void* SbrkSysAllocator::Alloc(size_t size, size_t *actual_size,

                              size_t alignment) {

#ifndef HAVE_SBRK

  failed_ = true;

  return NULL;

#else

  // Check if we should use sbrk allocation.

  // FLAGS_malloc_skip_sbrk starts out as false (its uninitialized

  // state) and eventually gets initialized to the specified value.  Note

  // that this code runs for a while before the flags are initialized.

  // That means that even if this flag is set to true, some (initial)

  // memory will be allocated with sbrk before the flag takes effect.

  if (FLAGS_malloc_skip_sbrk) {

    return NULL;

  }

//首先判断内存的分配是否采用sbrk,如果FLAGS_malloc_skip_sbrk设置为true那么代表着不适用sbrk,则直接返回NULL,代表分配失败。

  // sbrk will release memory if passed a negative number, so we do

  // a strict check here

  if (static_cast(size + alignment) < 0) return NULL;

//由于sbrk可以通过传入负值动态缩减heap顶部,因此在分配函数中把这种情况先排除。

  // This doesn't overflow because TCMalloc_SystemAlloc has already

  // tested for overflow at the alignment boundary.

  size = ((size + alignment - 1) / alignment) * alignment;

//通过alignment对齐,将非对齐的size转换为对齐

  // "actual_size" indicates that the bytes from the returned pointer

  // p up to and including (p + actual_size - 1) have been allocated.

  if (actual_size) {

    *actual_size = size;

  }

 

  // Check that we we're not asking for so much more memory that we'd

  // wrap around the end of the virtual address space.  (This seems

  // like something sbrk() should check for us, and indeed opensolaris

  // does, but glibc does not:

  //   

  //    ~checkout~/libc/misc/sbrk.c?rev=1.1.2.1&content-type=text/plain&cvsroot=glibc

  // Without this check, sbrk may succeed when it ought to fail.)

  if (reinterpret_cast(sbrk(0)) + size < size) {

    failed_ = true;

    return NULL;

  }//判断我们申请的size有没有超过进程空间能够提供的最大值

 

  void* result = sbrk(size);

  if (result == reinterpret_cast(-1)) {

    failed_ = true;

    return NULL;

  }

//利用sbrk申请size大小的空间

  // Is it aligned?

  uintptr_t ptr = reinterpret_cast(result);

  if ((ptr & (alignment-1)) == 0)  return result;

//如果申请成功,那么判断是否符合对齐要求,如果对齐,那么返回结果

  // Try to get more memory for alignment

  size_t extra = alignment - (ptr & (alignment-1));

  //如果没有对齐,那么判断还缺少多少size可以对齐,

  void* r2 = sbrk(extra);

 //申请需要的size进行对齐

  if (reinterpret_cast(r2) == (ptr + size)) {

    // Contiguous with previous result

    return reinterpret_cast(ptr + extra);

//符合对齐要求,那么返回结果

  }

 

  // Give up and ask for "size + alignment - 1" bytes so

  // that we can find an aligned region within it.

  result = sbrk(size + alignment - 1);//否者将不管对齐与否,申请一个比size大的空间,至少保证在这个空间内可以找到一块对齐的空间,这里面应该分为两种情况,第一种情况是以上分配都是失败的,第二种情况是分配没有失败,只是没有找到相应的对齐

  if (result == reinterpret_cast(-1)) {

    failed_ = true;

    return NULL;

  }

  ptr = reinterpret_cast(result);

  if ((ptr & (alignment-1)) != 0) {

    ptr += alignment - (ptr & (alignment-1));

         //保证ptr顶部对齐

  }

  return reinterpret_cast(ptr);

#endif  // HAVE_SBRK

}

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