Skip to content

Fix: Support setting thread names on more platforms than Linux #702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Apr 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions src/applications/bmqbrkr/m_bmqbrkr_task.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -279,12 +279,10 @@ int Task::initialize(bsl::ostream& errorDescription)
return rc_SCHEDULER_START_FAILED; // RETURN
}

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
d_scheduler.scheduleEvent(
bsls::TimeInterval(0, 0), // now
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedTask"));
}
d_scheduler.scheduleEvent(
bsls::TimeInterval(0, 0), // now
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedTask"));

// -------------
// LogController
Expand Down Expand Up @@ -344,10 +342,7 @@ int Task::initialize(bsl::ostream& errorDescription)
return rc_CONTROLCHANNEL_START_FAILED; // RETURN
}

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
bdls::PipeUtil::send(pipePath,
bsl::string(k_MTRAP_SET_THREADNAME) + "\n");
}
bdls::PipeUtil::send(pipePath, bsl::string(k_MTRAP_SET_THREADNAME) + "\n");

// -------------------
// M-Trap registration
Expand Down
4 changes: 1 addition & 3 deletions src/groups/bmq/bmqimp/bmqimp_brokersession.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5850,9 +5850,7 @@ void BrokerSession::setChannel(const bsl::shared_ptr<bmqio::Channel>& channel)
{
// executed by the *IO* thread

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
bmqsys::ThreadUtil::setCurrentThreadNameOnce("bmqTCPIO");
}
bmqsys::ThreadUtil::setCurrentThreadNameOnce("bmqTCPIO");

if (channel) { // We are now connected to bmqbrkr
BALL_LOG_INFO << "Channel is CREATED [host: " << channel->peerUri()
Expand Down
44 changes: 2 additions & 42 deletions src/groups/bmq/bmqsys/bmqsys_threadutil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,11 @@
#include <bsl_iostream.h>
#include <bsl_ostream.h>
#include <bslma_default.h>
#include <bslmt_threadutil.h>
#include <bsls_annotation.h>
#include <bsls_performancehint.h>
#include <bsls_platform.h>

// Linux
#if defined(BSLS_PLATFORM_OS_LINUX)
#include <sys/prctl.h>
#endif

namespace BloombergLP {
namespace bmqsys {

Expand All @@ -52,23 +48,9 @@ bslmt::ThreadAttributes ThreadUtil::defaultAttributes()
return attributes;
}

// LINUX
// -----
#if defined(BSLS_PLATFORM_OS_LINUX)

const bool ThreadUtil::k_SUPPORT_THREAD_NAME = true;

void ThreadUtil::setCurrentThreadName(const bsl::string& value)
{
int rc = prctl(PR_SET_NAME, value.c_str(), 0, 0, 0);
// We should use 'modern' APIs: pthread_setname_no(pthread_self()). But
// Bloomberg is a bit old; API was added in glibc 2.12, and we have 2.5.
if (rc != 0) {
BALL_LOG_SET_CATEGORY(k_LOG_CATEGORY);
BALL_LOG_ERROR << "Failed to set thread name " << "[name: '" << value
<< "'" << ", rc: " << rc << ", strerr: '"
<< bsl::strerror(rc) << "']";
}
bslmt::ThreadUtil::setThreadName(value);
}

void ThreadUtil::setCurrentThreadNameOnce(const bsl::string& value)
Expand All @@ -87,27 +69,5 @@ void ThreadUtil::setCurrentThreadNameOnce(const bsl::string& value)
}
}

// UNSUPPORTED_PLATFORMS
// ---------------------
#else

const bool ThreadUtil::k_SUPPORT_THREAD_NAME = false;

void ThreadUtil::setCurrentThreadName(
BSLS_ANNOTATION_UNUSED const bsl::string& value)
{
// NOT AVAILABLE

static_cast<void>(k_LOG_CATEGORY); // suppress unused variable warning
}

void ThreadUtil::setCurrentThreadNameOnce(
BSLS_ANNOTATION_UNUSED const bsl::string& value)
{
// NOT AVAILABLE
}

#endif

} // close package namespace
} // close enterprise namespace
26 changes: 10 additions & 16 deletions src/groups/bmq/bmqsys/bmqsys_threadutil.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,34 +47,28 @@ namespace bmqsys {

/// Utility namespace for thread management
struct ThreadUtil {
// CONSTANTS

/// Boolean constant indicating whether the current platform supports
/// naming thread.
static const bool k_SUPPORT_THREAD_NAME;

// CLASS METHODS

/// Return `bslmt::ThreadAttributes` object pre-initialized with default
/// thread parameter values set for the local operating system.
static bslmt::ThreadAttributes defaultAttributes();

/// Set the name of the current thread to the specified `value`. This
/// method is a no-op if `k_SUPPORT_THREAD_NAME` is false.
/// Set the name of the current thread to the specified `value`, truncated
/// to a length of 15 bytes.
///
/// PLATFORM NOTE:
/// - this functionality is only supported on LINUX, and the name can
/// be up to 15 characters.
/// - On platforms other than Linux, Solaris, Darwin, and Windows, this
/// method has no effect.
static void setCurrentThreadName(const bsl::string& value);

/// Set the name of the current thread to the specified `value`. This
/// method is a no-op if `k_SUPPORT_THREAD_NAME` is false. Unlike
/// `setCurrentThreadName`, this method uses a thread local variable to
/// ensure this is done only once per thread.
/// Set the name of the current thread to the specified `value`, truncated
/// to a length of 15 bytes. Unlike `setCurrentThreadName`, this method
/// uses a thread local variable to ensure this is done only once per
/// thread.
///
/// PLATFORM NOTE:
/// - this functionality is only supported on LINUX, and the name can
/// be up to 15 characters.
/// - On platforms other than Linux, Solaris, Darwin, and Windows, this
/// method has no effect.
static void setCurrentThreadNameOnce(const bsl::string& value);
};

Expand Down
20 changes: 9 additions & 11 deletions src/groups/mqb/mqba/mqba_dispatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,17 +522,15 @@ int Dispatcher::start(bsl::ostream& errorDescription)
return rc; // RETURN
}

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispSession"),
mqbi::DispatcherClientType::e_SESSION);
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispQueue"),
mqbi::DispatcherClientType::e_QUEUE);
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispCluster"),
mqbi::DispatcherClientType::e_CLUSTER);
}
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispSession"),
mqbi::DispatcherClientType::e_SESSION);
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispQueue"),
mqbi::DispatcherClientType::e_QUEUE);
execute(bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqDispCluster"),
mqbi::DispatcherClientType::e_CLUSTER);

d_isStarted = true;

Expand Down
14 changes: 6 additions & 8 deletions src/groups/mqb/mqbnet/mqbnet_elector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2234,15 +2234,13 @@ Elector::Elector(mqbcfg::ElectorConfig& config,

d_state.setTerm(initialTerm);

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
// Per scheduler's contract, it's ok to schedule events before its
// started.
// Per scheduler's contract, it's ok to schedule events before its
// started.

d_scheduler.scheduleEvent(
bsls::TimeInterval(0, 0), // now
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedElec"));
}
d_scheduler.scheduleEvent(
bsls::TimeInterval(0, 0), // now
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedElec"));
}

Elector::~Elector()
Expand Down
4 changes: 1 addition & 3 deletions src/groups/mqb/mqbnet/mqbnet_tcpsessionfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -656,9 +656,7 @@ void TCPSessionFactory::channelStateCallback(
// This is an infrequent enough operation (compared to a 'readCb') that it
// is fine to do this here (since we have no other ways to
// proactively-execute code in the IO threads created by the channelPool).
if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
bmqsys::ThreadUtil::setCurrentThreadNameOnce(d_threadName);
}
bmqsys::ThreadUtil::setCurrentThreadNameOnce(d_threadName);

BALL_LOG_TRACE << "TCPSessionFactory '" << d_config.name()
<< "': channelStateCallback [event: " << event
Expand Down
10 changes: 4 additions & 6 deletions src/groups/mqb/mqbstat/mqbstat_statcontroller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -725,12 +725,10 @@ int StatController::start(bsl::ostream& errorDescription)
return -2; // RETURN
}

if (bmqsys::ThreadUtil::k_SUPPORT_THREAD_NAME) {
d_scheduler_mp->scheduleEvent(
bsls::TimeInterval(0), // execute as soon as possible
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedStat"));
}
d_scheduler_mp->scheduleEvent(
bsls::TimeInterval(0), // execute as soon as possible
bdlf::BindUtil::bind(&bmqsys::ThreadUtil::setCurrentThreadName,
"bmqSchedStat"));

// Create and start the system stat monitor. The SystemStats are used in
// the dashboard screen, stat consumers, stats printer, ... So we need to
Expand Down
Loading