int main(int argc, const char **argv)
{
- ceph_pthread_setname(pthread_self(), "ceph-mds");
+ ceph_pthread_setname("ceph-mds");
auto args = argv_to_vec(argc, argv);
if (args.empty()) {
*/
int main(int argc, const char **argv)
{
- ceph_pthread_setname(pthread_self(), "ceph-mgr");
+ ceph_pthread_setname("ceph-mgr");
auto args = argv_to_vec(argc, argv);
if (args.empty()) {
{
// reset our process name, in case we did a respawn, so that it's not
// left as "exe".
- ceph_pthread_setname(pthread_self(), "ceph-mon");
+ ceph_pthread_setname("ceph-mon");
int err;
void *synthetic_client_thread_entry(void *ptr)
{
+ ceph_pthread_setname("client");
SyntheticClient *sc = static_cast<SyntheticClient*>(ptr);
//int r =
sc->run();
pthread_create(&thread_id, NULL, synthetic_client_thread_entry, this);
ceph_assert(thread_id);
- ceph_pthread_setname(thread_id, "client");
return 0;
}
if (pid && cpuid >= 0)
_set_affinity(cpuid);
- ceph_pthread_setname(pthread_self(), Thread::thread_name.c_str());
+ ceph_pthread_setname(thread_name.c_str());
return entry();
}
void Thread::create(const char *name, size_t stacksize)
{
ceph_assert(strlen(name) < 16);
- Thread::thread_name = name;
+ thread_name = name;
int ret = try_create(stacksize);
if (ret != 0) {
// Functions for std::thread
// =========================
-void set_thread_name(std::thread& t, const std::string& s) {
- int r = ceph_pthread_setname(t.native_handle(), s.c_str());
- if (r != 0) {
- throw std::system_error(r, std::generic_category());
- }
-}
-std::string get_thread_name(const std::thread& t) {
- std::string s(256, '\0');
-
- int r = ceph_pthread_getname(const_cast<std::thread&>(t).native_handle(),
- s.data(), s.length());
- if (r != 0) {
- throw std::system_error(r, std::generic_category());
- }
- s.resize(std::strlen(s.data()));
- return s;
-}
-
void kill(std::thread& t, int signal)
{
auto r = ceph_pthread_kill(t.native_handle(), signal);
#include "include/ceph_assert.h"
#include "include/compat.h"
-#include "include/spinlock.h"
extern pid_t ceph_gettid();
pthread_t thread_id;
pid_t pid;
int cpuid;
- static inline thread_local std::string thread_name;
+ std::string thread_name;
void *entry_wrapper();
int join(void **prval = 0);
int detach();
int set_affinity(int cpuid);
- static const std::string get_thread_name() {
- return Thread::thread_name;
- }
};
// Functions for with std::thread
-void set_thread_name(std::thread& t, const std::string& s);
-std::string get_thread_name(const std::thread& t);
void kill(std::thread& t, int signal);
template<typename Fun, typename... Args>
Args&& ...args) {
return std::thread([n = std::string(n)](auto&& fun, auto&& ...args) {
- ceph_pthread_setname(pthread_self(), n.data());
+ ceph_pthread_setname(n.data());
std::invoke(std::forward<Fun>(fun),
std::forward<Args>(args)...);
}, std::forward<Fun>(fun), std::forward<Args>(args)...);
g_assert_line = line;
g_assert_func = func;
g_assert_thread = (unsigned long long)pthread_self();
- ceph_pthread_getname(pthread_self(), g_assert_thread_name,
- sizeof(g_assert_thread_name));
+ ceph_pthread_getname(g_assert_thread_name, sizeof(g_assert_thread_name));
ostringstream tss;
tss << ceph_clock_now();
g_assert_line = line;
g_assert_func = func;
g_assert_thread = (unsigned long long)pthread_self();
- ceph_pthread_getname(pthread_self(), g_assert_thread_name,
- sizeof(g_assert_thread_name));
+ ceph_pthread_getname(g_assert_thread_name, sizeof(g_assert_thread_name));
BufAppender ba(g_assert_msg, sizeof(g_assert_msg));
BackTrace *bt = new ClibBackTrace(1);
g_assert_line = line;
g_assert_func = func;
g_assert_thread = (unsigned long long)pthread_self();
- ceph_pthread_getname(pthread_self(), g_assert_thread_name,
- sizeof(g_assert_thread_name));
+ ceph_pthread_getname(g_assert_thread_name, sizeof(g_assert_thread_name));
BackTrace *bt = new ClibBackTrace(1);
snprintf(g_assert_msg, sizeof(g_assert_msg),
g_assert_line = line;
g_assert_func = func;
g_assert_thread = (unsigned long long)pthread_self();
- ceph_pthread_getname(pthread_self(), g_assert_thread_name,
- sizeof(g_assert_thread_name));
+ ceph_pthread_getname(g_assert_thread_name, sizeof(g_assert_thread_name));
BufAppender ba(g_assert_msg, sizeof(g_assert_msg));
BackTrace *bt = new ClibBackTrace(1);
std::thread thread;
void timer_thread() {
+ ceph_pthread_setname("ceph_timer");
std::unique_lock l(lock);
while (!suspended) {
auto now = TC::now();
public:
timer() : suspended(false) {
thread = std::thread(&timer::timer_thread, this);
- set_thread_name(thread, "ceph_timer");
}
// Create a suspended timer, jobs will be executed in order when
* Foundation. See file COPYING.
*
*/
+#include "include/compat.h"
#include "common/code_environment.h"
#include "acconfig.h"
-#ifdef HAVE_PTHREAD_GETNAME_NP
-#include <pthread.h>
-#endif
-
#include <string.h>
code_environment_t g_code_env = CODE_ENVIRONMENT_UTILITY;
}
// FIPS zeroization audit 20191115: this memset is not security related.
memset(buf, 0, len);
- return pthread_getname_np(pthread_self(), buf, len);
+ return ceph_pthread_getname(buf, len);
}
#elif defined(HAVE_GETPROGNAME)
}
#endif /* _WIN32 */
+
+
+static thread_local char cached_thread_name[256]{};
+
+int ceph_pthread_setname(char const* name)
+{
+ strncpy(cached_thread_name, name, sizeof cached_thread_name - 1);
+#if defined(_WIN32) && defined(__clang__) && \
+ !defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+ // In this case, llvm doesn't use the pthread api for std::thread.
+ // We cannot use native_handle() with the pthread api, nor can we pass
+ // it to Windows API functions.
+ return 0;
+#elif defined(HAVE_PTHREAD_SETNAME_NP)
+ #if defined(__APPLE__)
+ return pthread_setname_np(name);
+ #else
+ return pthread_setname_np(pthread_self(), name);
+ #endif
+#elif defined(HAVE_PTHREAD_SET_NAME_NP)
+ pthread_set_name_np(pthread_self(), name); \
+ return 0;
+#else
+ return 0;
+#endif
+}
+
+int ceph_pthread_getname(char* name, size_t len)
+{
+ if (cached_thread_name[0]) {
+ if (len > 0) {
+ strncpy(name, cached_thread_name, len);
+ name[len-1] = 0;
+ }
+ return 0;
+ } else {
+#if defined(_WIN32) && defined(__clang__) && \
+ !defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
+ if (len > 0) {
+ strcpy(name, "");
+ }
+ return 0;
+#elif defined(HAVE_PTHREAD_GETNAME_NP) || defined(HAVE_PTHREAD_GET_NAME_NP)
+# if defined(HAVE_PTHREAD_GETNAME_NP)
+ int rc = pthread_getname_np(pthread_self(), cached_thread_name, sizeof cached_thread_name);
+# else
+ int rc = pthread_get_name_np(pthread_self(), cached_thread_name, sizeof cached_thread_name);
+# endif
+ if (rc == 0) {
+ strncpy(name, cached_thread_name, len);
+ name[len-1] = 0;
+ return 0;
+ } else {
+ return rc;
+ }
+#else
+ if (len > 0) {
+ strcpy(name, "");
+ }
+ return 0;
+#endif
+ }
+}
}
void *ObjBencher::status_printer(void *_bencher) {
+ ceph_pthread_setname("OB::stat_print");
ObjBencher *bencher = static_cast<ObjBencher *>(_bencher);
bench_data& data = bencher->data;
Formatter *formatter = bencher->formatter;
pthread_t print_thread;
pthread_create(&print_thread, NULL, ObjBencher::status_printer, (void *)this);
- ceph_pthread_setname(print_thread, "write_stat");
std::unique_lock locker{lock};
data.finished = 0;
data.start_time = mono_clock::now();
pthread_t print_thread;
pthread_create(&print_thread, NULL, status_printer, (void *)this);
- ceph_pthread_setname(print_thread, "seq_read_stat");
mono_time finish_time = data.start_time + time_to_run;
//start initial reads
pthread_t print_thread;
pthread_create(&print_thread, NULL, status_printer, (void *)this);
- ceph_pthread_setname(print_thread, "rand_read_stat");
mono_time finish_time = data.start_time + time_to_run;
//start initial reads
pin(*cpus);
}
block_sighup();
- (void) pthread_setname_np(pthread_self(), "alien-store-tp");
+ (void) ceph_pthread_setname("alien-store-tp");
loop(queue_max_wait, i);
});
}
char buf[1024];
char pthread_name[16] = {0}; //limited by 16B include terminating null byte.
- int r = ceph_pthread_getname(pthread_self(), pthread_name, sizeof(pthread_name));
+ int r = ceph_pthread_getname(pthread_name, sizeof(pthread_name));
(void)r;
#if defined(__sun)
char message[SIG2STR_MAX];
#define MSG_DONTWAIT MSG_NONBLOCK
#endif
-/* compiler warning free success noop */
-#define pthread_setname_noop_helper(thread, name) ({ \
- int __i = 0; \
- __i; })
-
-#define pthread_getname_noop_helper(thread, name, len) ({ \
- if (name != NULL) \
- *name = '\0'; \
- 0; })
-
#define pthread_kill_unsupported_helper(thread, signal) ({ \
int __i = -ENOTSUP; \
__i; })
-#if defined(_WIN32) && defined(__clang__) && \
- !defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
- // In this case, llvm doesn't use the pthread api for std::thread.
- // We cannot use native_handle() with the pthread api, nor can we pass
- // it to Windows API functions.
- #define ceph_pthread_setname pthread_setname_noop_helper
-#elif defined(HAVE_PTHREAD_SETNAME_NP)
- #if defined(__APPLE__)
- #define ceph_pthread_setname(thread, name) ({ \
- int __result = 0; \
- if (thread == pthread_self()) \
- __result = pthread_setname_np(name); \
- __result; })
- #else
- #define ceph_pthread_setname pthread_setname_np
- #endif
-#elif defined(HAVE_PTHREAD_SET_NAME_NP)
- /* Fix a small name diff and return 0 */
- #define ceph_pthread_setname(thread, name) ({ \
- pthread_set_name_np(thread, name); \
- 0; })
-#else
- #define ceph_pthread_setname pthread_setname_noop_helper
-#endif
-
-#if defined(_WIN32) && defined(__clang__) && \
- !defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
- #define ceph_pthread_getname pthread_getname_noop_helper
-#elif defined(HAVE_PTHREAD_GETNAME_NP)
- #define ceph_pthread_getname pthread_getname_np
-#elif defined(HAVE_PTHREAD_GET_NAME_NP)
- #define ceph_pthread_getname(thread, name, len) ({ \
- pthread_get_name_np(thread, name, len); \
- 0; })
-#else
- #define ceph_pthread_getname pthread_getname_noop_helper
-#endif
-
#if defined(_WIN32) && defined(__clang__) && \
!defined(_LIBCPP_HAS_THREAD_API_PTHREAD)
#define ceph_pthread_kill pthread_kill_unsupported_helper
extern "C" {
#endif
+int ceph_pthread_getname(char* name, size_t size);
+int ceph_pthread_setname(const char* name);
+
int pipe_cloexec(int pipefd[2], int flags);
char *ceph_strerror_r(int errnum, char *buf, size_t buflen);
unsigned get_page_size();
class Entry {
public:
using time = log_time;
+ using thread_name_t = std::array<char, 16>;
Entry() = delete;
Entry(short pr, short sub) :
m_prio(pr),
m_subsys(sub)
{
- strncpy(m_thread_name, Thread::get_thread_name().data(), 16);
- m_thread_name[15] = '\0';
+ ceph_pthread_getname(m_thread_name.data(), m_thread_name.size());
}
Entry(const Entry &) = default;
Entry& operator=(const Entry &) = default;
time m_stamp;
pthread_t m_thread;
short m_prio, m_subsys;
- char m_thread_name[16];
+ thread_name_t m_thread_name{};
static log_clock& clock() {
static log_clock clock;
m_recent.clear();
for (const auto& e : t) {
auto& set = recent_pthread_ids[e.m_thread];
- set.insert(e.m_thread_name);
+ set.insert(e.m_thread_name.data());
}
_flush(t, true);
}
_notify_mdsmap(mdsmap);
sender = std::thread([this]() {
+ ceph_pthread_setname("beacon");
std::unique_lock<std::mutex> lock(mutex);
bool sent;
while (!finished) {
static constexpr int TASK_COMM_LEN = 16;
char tp_name[TASK_COMM_LEN];
sprintf(tp_name, "msgr-worker-%u", id);
- ceph_pthread_setname(pthread_self(), tp_name);
+ ceph_pthread_setname(tp_name);
}
protected:
ceph_assert(rx_cq);
t = std::thread(&RDMADispatcher::polling, this);
- ceph_pthread_setname(t.native_handle(), "rdma-polling");
}
void RDMADispatcher::polling_stop()
void RDMADispatcher::polling()
{
+ ceph_pthread_setname("rdma-polling");
static int MAX_COMPLETIONS = 32;
ibv_wc wc[MAX_COMPLETIONS];
#include "services/svc_zone.h"
#include "common/dout.h"
#include <chrono>
+#include <fmt/format.h>
#define dout_subsys ceph_subsys_rgw
});
// start the worker threads to do the actual queue processing
- const std::string WORKER_THREAD_NAME = "notif-worker";
for (auto worker_id = 0U; worker_id < worker_count; ++worker_id) {
- workers.emplace_back([this]() {
+ workers.emplace_back([this,worker_id]() {
+ const auto thread_name = fmt::format("notif-worker-{}", worker_id);
+ ceph_pthread_setname(thread_name.c_str());
try {
io_context.run();
} catch (const std::exception& err) {
throw err;
}
});
- const auto thread_name = WORKER_THREAD_NAME+std::to_string(worker_id);
- if (const auto rc = ceph_pthread_setname(workers.back().native_handle(), thread_name.c_str()); rc != 0) {
- ldpp_dout(this, 1) << "ERROR: failed to set notification manager thread name to: " << thread_name
- << ". error: " << rc << dendl;
- }
}
ldpp_dout(this, 10) << "INfO: started notification manager with: " << worker_count << " workers" << dendl;
}
// (4) TODO reconnect on connection errors
// (5) TODO cleanup timedout callbacks
void run() noexcept {
+ // give the runner thread a name for easier debugging
+ ceph_pthread_setname("amqp_manager");
+
amqp_frame_t frame;
while (!stopped) {
// This is to prevent rehashing so that iterators are not invalidated
// when a new connection is added.
connections.max_load_factor(10.0);
- // give the runner thread a name for easier debugging
- const char* thread_name = "amqp_manager";
- if (const auto rc = ceph_pthread_setname(runner.native_handle(), thread_name); rc != 0) {
- ldout(cct, 1) << "ERROR: failed to set amqp manager thread name to: " << thread_name
- << ". error: " << rc << dendl;
- }
}
// non copyable
}
void run() noexcept {
+ ceph_pthread_setname("kafka_manager");
while (!stopped) {
// publish all messages in the queue
// This is to prevent rehashing so that iterators are not invalidated
// when a new connection is added.
connections.max_load_factor(10.0);
- // give the runner thread a name for easier debugging
- const char* thread_name = "kafka_manager";
- if (const auto rc = ceph_pthread_setname(runner.native_handle(), thread_name); rc != 0) {
- ldout(cct, 1) << "ERROR: failed to set kafka manager thread name to: " << thread_name
- << ". error: " << rc << dendl;
- }
}
// non copyable
}
started = true;
runner = std::thread(&Background::run, this);
- const char* thread_name = "lua_background";
- if (const auto rc = ceph_pthread_setname(runner.native_handle(), thread_name); rc != 0) {
- ldout(cct, 1) << "ERROR: failed to set lua background thread name to: " << thread_name
- << ". error: " << rc << dendl;
- }
}
void Background::pause() {
//(2) Executes the script
//(3) Sleep (configurable)
void Background::run() {
+ ceph_pthread_setname("lua_background");
const DoutPrefixProvider* const dpp = &dp;
lua_state_guard lguard(cct->_conf->rgw_lua_max_memory_per_state, dpp);
auto L = lguard.get();
std::atomic_uint8_t current_active = 0;
std::shared_ptr<RateLimiter> ratelimit[2];
void replace_active() {
+ ceph_pthread_setname("ratelimit_gc");
using namespace std::chrono_literals;
std::unique_lock<std::mutex> lk(cv_m);
while (!stopped) {
void start() {
ldpp_dout(this, 20) << "starting ratelimit_gc thread" << dendl;
runner = std::thread(&ActiveRateLimiter::replace_active, this);
- if (const auto rc = ceph_pthread_setname(runner.native_handle(), "ratelimit_gc"); rc != 0) {
- ldpp_dout(this, 1) << "ERROR: failed to set ratelimit_gc thread name. error: " << rc << dendl;
- }
}
};