From 6fb416b083d518e5f524359cc3cacb66ccc63dca Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Tue, 15 Feb 2011 11:02:03 -0800 Subject: [PATCH] common: thread: get number of threads from /proc 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 --- src/Makefile.am | 1 + src/common/Thread.cc | 54 ++++++++++++++++++++++++++++++++++++++ src/common/Thread.h | 9 +++---- src/config.cc | 2 -- src/msg/SimpleMessenger.cc | 5 ++-- 5 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 src/common/Thread.cc diff --git a/src/Makefile.am b/src/Makefile.am index 9074671f5a1af..3cdf2864cf01a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 index 0000000000000..148a6caa51aed --- /dev/null +++ b/src/common/Thread.cc @@ -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 +#include +#include +#include +#include +#include + +#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; +} diff --git a/src/common/Thread.h b/src/common/Thread.h index 35984e7d88a81..a6de02286754d 100644 --- a/src/common/Thread.h +++ b/src/common/Thread.h @@ -17,14 +17,13 @@ #define CEPH_THREAD_H #include "common/signal.h" +#include "config.h" #include "include/atomic.h" #include #include #include -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; diff --git a/src/config.cc b/src/config.cc index 78188944abf23..b96be8ec94de8 100644 --- a/src/config.cc +++ b/src/config.cc @@ -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), diff --git a/src/msg/SimpleMessenger.cc b/src/msg/SimpleMessenger.cc index 620062736a4bb..d93e5ccddf3b8 100644 --- a/src/msg/SimpleMessenger.cc +++ b/src/msg/SimpleMessenger.cc @@ -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; } -- 2.39.5