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

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 15:59:01

以上过程是span_allocator_.Init()函数的行为,到此已经分析完毕,下面我们继续看Static::InitStaticVars函数,次函数接着将会调用函数stacktrace_allocator_.Init();stacktrace_allocator_的定义如下,PageHeapAllocator Static::stacktrace_allocator_;这个函数的init也是和span一样,都是为这两个obj预留了相应的空间,并进行了初始化。然后调用bucket_allocator_.Init(),结果也是如上。void Static::InitStaticVars() {

  sizemap_.Init();

  span_allocator_.Init();

  span_allocator_.New(); // Reduce cache conflicts

  span_allocator_.New(); // Reduce cache conflicts

  stacktrace_allocator_.Init();

  bucket_allocator_.Init();

  // Do a bit of sanitizing: make sure central_cache is aligned properly

  CHECK_CONDITION((sizeof(central_cache_[0]) % 64) == 0);

  for (int i = 0; i < kNumClasses; ++i) {

    central_cache_[i].Init(i);

  }

  new ((void*)pageheap_memory_) PageHeap;

  DLL_Init(&sampled_objects_);

  Sampler::InitStatics();

}

 

后面开始初始化central_cachecentral_cache作为整个tcmalloc的核心数据结构,他包含kNumClasses()个CentralFreeListPadded。每个CentralFreeListPadded64bytes对齐,通过一个  char pad_[64 - kFreeListSizeMod64]来实现对齐。

templateclass CentralFreeListPaddedTo : public CentralFreeList {

 private:

  char pad_[64 - kFreeListSizeMod64];

};

template<>class CentralFreeListPaddedTo<0> : public CentralFreeList {

};

 

class CentralFreeListPadded : public CentralFreeListPaddedTo<  sizeof(CentralFreeList) % 64> {

};

central_cache_的每个class都会通过调用下面的init函数进行初始化,init函数的调用参数为当前classnum,通过classnum初始化CentralFreeListsize_class_(本classclass num,通过class_to_size_可获得本class可以分配的最大objsize)。DLL_Init只是简单的将spannextprev指针指向自己。然后初始化counter_=0(Number of free objects in cache entry)cache_size_used_slots_的初始化和数据结构TCEntry tc_slots_[kNumTransferEntries]有关,TCEntry主要用来cache thread caches and the central cache之间的transfers of sizemap.num_objects_to_move(size_class) used_slots_代表现在正在使用中的tc_slots_数量,而cache_size_代表当前可使用的slots,当然这个数字可根据流量动态调整。

void CentralFreeList::Init(size_t cl) {

  size_class_ = cl;

  tcmalloc::DLL_Init(&empty_);

  tcmalloc::DLL_Init(&nonempty_);

  counter_ = 0;

 

  cache_size_ = 1;

  used_slots_ = 0;

  ASSERT(cache_size_ <= kNumTransferEntries);

}

初始化完毕central_cache_后调用PageHeap的构造函数对char Static::pageheap_memory_[sizeof(PageHeap)]进行初始化。PageHeap的初始化函数如下所示,首先初始化pagemap_page_map是一个三层的radix tree,他的初始化函数通过设置allocatorMetaDataAlloc,并利用MetaDataAlloc new出一个node作为rootpagemap_cache_是一个PackedCache。他主要用作minimal cache that can hold a 。每个cache entry都用一对来表示。free_ list主要用来存储本PageHeap中的各个sizespan

 

PageHeap::PageHeap()

    : pagemap_(MetaDataAlloc),

      pagemap_cache_(0),

      scavenge_counter_(0),

      // Start scavenging at kMaxPages list

      release_index_(kMaxPages) {

  COMPILE_ASSERT(kNumClasses <= (1 << PageMapCache::kValuebits), valuebits);

  DLL_Init(&large_.normal);

  DLL_Init(&large_.returned);

  for (int i = 0; i < kMaxPages; i++) {

    DLL_Init(&free_[i].normal);

    DLL_Init(&free_[i].returned);

  }

}

 

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