ceph源码分析--一个entry函数的调用

ceph中有很多的entry函数,往往是由各线程来调用处理的,本篇文章以bluestore中的MempoolThread为例来讲讲该函数的调用。

 struct MempoolThread : public Thread {
    BlueStore *store;
    Cond cond;
    Mutex lock;
    bool stop = false;
  public:
    explicit MempoolThread(BlueStore *s)
      : store(s),
    lock("BlueStore::MempoolThread::lock") {}
    void *entry() override;
    void init() {
      assert(stop == false);
      create("bstore_mempool");
    }
    void shutdown() {
      lock.Lock();
      stop = true;
      cond.Signal();
      lock.Unlock();
      join();
    }
  } ;

首先查看其init函数,调用了父类Thread的create(“bstore_mempool”)

void init() {
    assert(stop == false);
    create("bstore_mempool");
}

void Thread::create(const char *name, size_t stacksize),调用了try_create(stacksize)

void Thread::create(const char *name, size_t stacksize)
{
  assert(strlen(name) < 16);
  thread_name = name;

  int ret = try_create(stacksize);
  if (ret != 0) {
    char buf[256];
    snprintf(buf, sizeof(buf), "Thread::try_create(): pthread_create "
         "failed with error %d", ret);
    dout_emergency(buf);
    assert(ret == 0);
  }
}

int Thread::try_create(size_t stacksize)调用了pthread_create(&thread_id, thread_attr, _entry_func, (void*)this),这是线程创建函数,关注_entry_func

int Thread::try_create(size_t stacksize)
{
  pthread_attr_t *thread_attr = NULL;
  pthread_attr_t thread_attr_loc;

  stacksize &= CEPH_PAGE_MASK;  // must be multiple of page
  if (stacksize) {
    thread_attr = &thread_attr_loc;
    pthread_attr_init(thread_attr);
    pthread_attr_setstacksize(thread_attr, stacksize);
  }

  int r;

  // The child thread will inherit our signal mask.  Set our signal mask to
  // the set of signals we want to block.  (It's ok to block signals more
  // signals than usual for a little while-- they will just be delivered to
  // another thread or delieverd to this thread later.)
  sigset_t old_sigset;
  if (g_code_env == CODE_ENVIRONMENT_LIBRARY) {
    block_signals(NULL, &old_sigset);
  }
  else {
    int to_block[] = { SIGPIPE , 0 };
    block_signals(to_block, &old_sigset);
  }
  r = pthread_create(&thread_id, thread_attr, _entry_func, (void*)this);
  restore_sigset(&old_sigset);

  if (thread_attr) {
    pthread_attr_destroy(thread_attr);  
  }

  return r;
}

void Thread::_entry_func(void *arg) 调用了((Thread)arg)->entry_wrapper()

void *Thread::_entry_func(void *arg) {
  void *r = ((Thread*)arg)->entry_wrapper();
  return r;
}

void *Thread::entry_wrapper()调用到entry~~~~旅行结束

void *Thread::entry_wrapper()
{
  int p = ceph_gettid(); // may return -ENOSYS on other platforms
  if (p > 0)
    pid = p;
  if (pid &&
      ioprio_class >= 0 &&
      ioprio_priority >= 0) {
    ceph_ioprio_set(IOPRIO_WHO_PROCESS,
            pid,
            IOPRIO_PRIO_VALUE(ioprio_class, ioprio_priority));
  }
  if (pid && cpuid >= 0)
    _set_affinity(cpuid);

  ceph_pthread_setname(pthread_self(), thread_name);
  return entry();
}

你可能感兴趣的:(Ceph)