]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: thread: get number of threads from /proc
authorColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 15 Feb 2011 19:02:03 +0000 (11:02 -0800)
committerColin Patrick McCabe <cmccabe@alumni.cmu.edu>
Tue, 15 Feb 2011 19:02:03 +0000 (11:02 -0800)
The kernel knows how many threads we have; just ask it. One less atomic
variable to carry around.

We will eventually have to avoid doing this check for non-daemon code,
but that's a separate issue.

Signed-off-by: Colin McCabe <colin.mccabe@dreamhost.com>
src/Makefile.am
src/common/Thread.cc [new file with mode: 0644]
src/common/Thread.h
src/config.cc
src/msg/SimpleMessenger.cc

index 9074671f5a1afe27665371b2d4a80f54d795137b..3cdf2864cf01a1b6b8a710b564fc1bc1e2d512d9 100644 (file)
@@ -525,6 +525,7 @@ libcommon_files = \
        common/common_init.cc \
        common/buffer.cc \
        common/signal.cc \
+       common/Thread.cc \
        include/ceph_fs.cc \
        include/ceph_hash.cc \
        include/ceph_strings.cc \
diff --git a/src/common/Thread.cc b/src/common/Thread.cc
new file mode 100644 (file)
index 0000000..148a6ca
--- /dev/null
@@ -0,0 +1,54 @@
+ // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include <dirent.h>
+#include <errno.h>
+#include <iostream>
+#include <sstream>
+#include <string.h>
+#include <sys/types.h>
+
+#include "common/debug.h"
+#include "common/Thread.h"
+
+int Thread::get_num_threads(void)
+{
+  std::ostringstream oss;
+  oss << "/proc/" << getpid() << "/task";
+  DIR *dir = opendir(oss.str().c_str());
+  if (!dir) {
+    int err = errno;
+    generic_dout(-1) << "is_multithreaded: failed to open '"
+       << oss.str() << "'" << dendl;
+    return -err;
+  }
+  int num_entries = 0;
+  while (true) {
+    struct dirent *e = readdir(dir);
+    if (!e)
+      break;
+    if ((strcmp(e->d_name, ".") == 0) ||
+        (strcmp(e->d_name, "..") == 0))
+      continue;
+    num_entries++;
+  }
+  ::closedir(dir);
+  if (num_entries == 0) {
+    // Shouldn't happen.
+    generic_dout(-1) << "is_multithreaded: no entries found in '"
+       << oss.str() << "'" << dendl;
+    return -EINVAL;
+  }
+  return num_entries;
+}
index 35984e7d88a81f01e7ab70821ce5a0641af36475..a6de02286754defc55d776e2a4efb00e59e340dc 100644 (file)
 #define CEPH_THREAD_H
 
 #include "common/signal.h"
+#include "config.h"
 #include "include/atomic.h"
 
 #include <errno.h>
 #include <pthread.h>
 #include <signal.h>
 
-extern atomic_t _num_threads;  // hack: in config.cc
-
 class Thread {
  private:
   pthread_t thread_id;
@@ -39,17 +38,16 @@ class Thread {
  private:
   static void *_entry_func(void *arg) {
     void *r = ((Thread*)arg)->entry();
-    _num_threads.dec();
     return r;
   }
 
  public:
+  static int get_num_threads(void);
+
   pthread_t &get_thread_id() { return thread_id; }
   bool is_started() { return thread_id != 0; }
   bool am_self() { return (pthread_self() == thread_id); }
 
-  static int get_num_threads() { return _num_threads.read(); }
-
   int kill(int signal) {
     if (thread_id)
       return pthread_kill(thread_id, signal);
@@ -82,7 +80,6 @@ class Thread {
       char buf[80];
       generic_dout(0) << "pthread_create failed with message: " << strerror_r(r, buf, sizeof(buf)) << dendl;
     } else {
-      _num_threads.inc();
       generic_dout(10) << "thread " << thread_id << " start" << dendl;
     }
     return r;
index 78188944abf23b96fb179d85c71f03c0b7cd5e4d..b96be8ec94de845962476bafec9fdfb55098d147 100644 (file)
@@ -51,8 +51,6 @@ md_config_t g_conf __attribute__((init_priority(103)));
 /* These should be moved into md_config_t eventually, grrr */
 static ConfFile *cf = NULL;
 
-atomic_t _num_threads(0);
-
 // file layouts
 struct ceph_file_layout g_default_file_layout = {
  fl_stripe_unit: init_le32(1<<22),
index 620062736a4bb5c86582f53e8bf99c64aaa3ae4a..d93e5ccddf3b81c34232fbfb7175bd88bebe8c16 100644 (file)
@@ -2427,8 +2427,9 @@ int SimpleMessenger::start(bool nodaemon)
 
   // daemonize?
   if (g_conf.daemonize && !nodaemon) {
-    if (Thread::get_num_threads() > 0) {
-      derr << "messenger.start BUG: there are " << Thread::get_num_threads()
+    int num_threads = Thread::get_num_threads();
+    if (num_threads > 0) {
+      derr << "messenger.start BUG: there are " << num_threads << " threads"
           << " already started that will now die!  call messenger.start() sooner."
           << dendl;
     }