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

全部博文(19)

文章存档

2012年(2)

2011年(17)

我的朋友

分类: LINUX

2011-10-08 16:00:41

Static::InitStaticVars()最后将调用Sampler::InitStatics()函数,此函数主要初始化sampler的采样间隔之类的。到此Static::InitStaticVars介绍完毕,我们返回ThreadCache::InitModule(),接着static::InitStaticVars开始初始化threadcache_allocatorthreadcache_allocator的定义是PageHeapAllocator,他的初始化函数也是PageHeapAllocator::init,此函数在上面已经解释。初始化结束后,设置phinited1防止多次初始化。

完成InitModule的解释,我们返回函数inline ThreadCache* ThreadCache::GetCache,由于ptrnull,那么调用:CreateCacheIfNecessary创建一个threadcache。代码分析如下

ThreadCache* ThreadCache::CreateCacheIfNecessary() {

  // Initialize per-thread data if necessary

  ThreadCache* heap = NULL;

  {

    SpinLockHolder h(Static::pageheap_lock());

//首先获取整个pageheap的锁

    // Early on in glibc's life, we cannot even call pthread_self()

    pthread_t me;

    if (!tsd_inited_) {

      memset(&me, 0, sizeof(me));//由于尚未初始化不能callll pthread_self,因此将me置为0

    } else {

      me = pthread_self();//如果已经初始化完毕,那么直接调用pthread_self获得tid

    }

 

    // This may be a recursive malloc call from pthread_setspecific()

    // In that case, the heap for this thread has already been created

    // and added to the linked list.  So we search for that first.

    for (ThreadCache* h = thread_heaps_; h != NULL; h = h->next_) {

      if (h->tid_ == me) {

        heap = h;

        break;

      }

    }

//通过对thread_heaps_列表进行遍历,判断本threadcache是否已经创建

    if (heap == NULL) heap = NewHeap(me);

  }

//如果没有找到,那么调用NewHeap分配一个新的heap

//下面部分没怎么看懂,应该是对pthread_setspecific调用进行特殊处理,防止对malloc的递归call方面。

  // We call pthread_setspecific() outside the lock because it may

  // call malloc() recursively.  We check for the recursive call using

  // the "in_setspecific_" flag so that we can avoid calling

  // pthread_setspecific() if we are already inside pthread_setspecific().

  if (!heap->in_setspecific_ && tsd_inited_) {

    heap->in_setspecific_ = true;

    perftools_pthread_setspecific(heap_key_, heap);

#ifdef HAVE_TLS

    // Also keep a copy in __thread for faster retrieval

    threadlocal_heap_ = heap;

#endif

    heap->in_setspecific_ = false;

  }

  return heap;

}

下面我们分析一下NewHeap函数,NewHeap函数通过threadcache_allocator.New分配一个threadCache,并调用ThreadCache.init进行初始化,并将新生成的heap加入thread_heaps_列表,这里有一个特殊的变量next_memory_steal,用来标识当当一个threadthread_Cache超过max_size_时从哪个cache偷内存,next_memory_steal采用Round-robin方式在各个thread cache中转移。

ThreadCache* ThreadCache::NewHeap(pthread_t tid) {

  // Create the heap and add it to the linked list

  ThreadCache *heap = threadcache_allocator.New();

  heap->Init(tid);

  heap->next_ = thread_heaps_;

  heap->prev_ = NULL;

  if (thread_heaps_ != NULL) {

    thread_heaps_->prev_ = heap;

  } else {

    // This is the only thread heap at the momment.

    ASSERT(next_memory_steal_ == NULL);

    next_memory_steal_ = heap;

  }

  thread_heaps_ = heap;

  thread_heap_count_++;

  return heap;

}

NewHeap中关键的函数是threadcache_allocator.Newthreadcache_allocator是一个PageHeapAllocator的对象,他的New函数在前面我们已经分析过了,主要是从threadcache_allocatorfree_list里面切出一个ThreadCache对象并赋值给heap

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