diff --git a/include/xrpl/basics/ThreadUtilities.h b/include/xrpl/basics/ThreadUtilities.h new file mode 100644 index 00000000000..f91dbd118e4 --- /dev/null +++ b/include/xrpl/basics/ThreadUtilities.h @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2022 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#ifndef RIPPLE_BASICS_THREADUTILITIES_H_INCLUDED +#define RIPPLE_BASICS_THREADUTILITIES_H_INCLUDED + +#include +#include + +namespace ripple { + +std::string +get_name(std::thread::native_handle_type t); + +template +inline auto +get_name(Thread& t) -> decltype(t.native_handle(), t.join(), std::string{}) +{ + return get_name(t.native_handle()); +} + +namespace this_thread { + +std::string +get_name(); + +void +set_name(std::string s); + +} // namespace this_thread + +} // namespace ripple + +#endif diff --git a/include/xrpl/beast/core/CurrentThreadName.h b/include/xrpl/beast/core/CurrentThreadName.h index 5adbb210880..f91dbd118e4 100644 --- a/include/xrpl/beast/core/CurrentThreadName.h +++ b/include/xrpl/beast/core/CurrentThreadName.h @@ -1,11 +1,7 @@ //------------------------------------------------------------------------------ /* - This file is part of Beast: https://github.com/vinniefalco/Beast - Copyright 2013, Vinnie Falco - - Portions of this file are from JUCE. - Copyright (c) 2013 - Raw Material Software Ltd. - Please visit http://www.juce.com + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2022 Ripple Labs Inc. Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above @@ -21,31 +17,34 @@ */ //============================================================================== -#ifndef BEAST_CORE_CURRENT_THREAD_NAME_H_INCLUDED -#define BEAST_CORE_CURRENT_THREAD_NAME_H_INCLUDED +#ifndef RIPPLE_BASICS_THREADUTILITIES_H_INCLUDED +#define RIPPLE_BASICS_THREADUTILITIES_H_INCLUDED #include -#include +#include -namespace beast { +namespace ripple { -/** Changes the name of the caller thread. - Different OSes may place different length or content limits on this name. -*/ -void -setCurrentThreadName(std::string_view newThreadName); +std::string +get_name(std::thread::native_handle_type t); -/** Returns the name of the caller thread. +template +inline auto +get_name(Thread& t) -> decltype(t.native_handle(), t.join(), std::string{}) +{ + return get_name(t.native_handle()); +} - The name returned is the name as set by a call to setCurrentThreadName(). - If the thread name is set by an external force, then that name change - will not be reported. +namespace this_thread { - If no name has ever been set, then the empty string is returned. -*/ std::string -getCurrentThreadName(); +get_name(); + +void +set_name(std::string s); + +} // namespace this_thread -} // namespace beast +} // namespace ripple #endif diff --git a/src/libxrpl/basics/ThreadUtilities.cpp b/src/libxrpl/basics/ThreadUtilities.cpp new file mode 100644 index 00000000000..be1745c40a7 --- /dev/null +++ b/src/libxrpl/basics/ThreadUtilities.cpp @@ -0,0 +1,140 @@ +//------------------------------------------------------------------------------ +/* + This file is part of rippled: https://github.com/ripple/rippled + Copyright (c) 2022 Ripple Labs Inc. + + Permission to use, copy, modify, and/or distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + + THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +*/ +//============================================================================== + +#include +#include + +namespace ripple { + +#ifdef __APPLE__ + +#include + +std::string +get_name(std::thread::native_handle_type t) +{ + char buffer[64]; + if (pthread_getname_np(t, buffer, sizeof(buffer)) != 0) + throw std::runtime_error("get_name failed\n"); + return buffer; +} + +namespace this_thread { + +std::string +get_name() +{ + return ripple::get_name(pthread_self()); +} + +void +set_name(std::string s) +{ + s.resize(15); + if (pthread_setname_np(s.data()) != 0) + throw std::runtime_error("this_thread::set_name failed\n"); +} + +} // namespace this_thread + +#endif // __APPLE__ + +#ifdef __linux__ + +#include + +std::string +get_name(std::thread::native_handle_type t) +{ + char buffer[64]; + if (pthread_getname_np(t, buffer, sizeof(buffer)) != 0) + throw std::runtime_error("get_name failed\n"); + return buffer; +} + +namespace this_thread { + +std::string +get_name() +{ + return ripple::get_name(pthread_self()); +} + +void +set_name(std::string s) +{ + s.resize(15); + if (pthread_setname_np(pthread_self(), s.data()) != 0) + throw std::runtime_error("this_thread::set_name failed\n"); +} + +} // namespace this_thread + +#endif // __linux__ + +#ifdef _WIN64 + +#define WIN32_LEAN_AND_MEAN + +#include +#include +#include + +std::string +get_name(std::thread::native_handle_type t) +{ + wchar_t* unhandled_data{}; + HRESULT r = GetThreadDescription(t, &unhandled_data); + std::unique_ptr data{ + unhandled_data, LocalFree}; + if (FAILED(r)) + throw std::runtime_error("get_name failed\n"); + std::string s; + auto p = data.get(); + while (*p) + s.push_back(static_cast(*p++)); + return s; +} + +namespace this_thread { + +std::string +get_name() +{ + return ripple::get_name(GetCurrentThread()); +} + +void +set_name(std::string s) +{ + assert(s.size() <= 15); + s.resize(15); + std::wstring ws; + for (auto c : s) + ws += c; + HRESULT r = SetThreadDescription(GetCurrentThread(), ws.data()); + if (FAILED(r)) + throw std::runtime_error("this_thread::set_name failed\n"); +} + +} // namespace this_thread + +#endif // __WINDOWS__ + +} // namespace ripple diff --git a/src/libxrpl/resource/ResourceManager.cpp b/src/libxrpl/resource/ResourceManager.cpp index d73ca090024..558e211a4bf 100644 --- a/src/libxrpl/resource/ResourceManager.cpp +++ b/src/libxrpl/resource/ResourceManager.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -148,7 +149,7 @@ class ManagerImp : public Manager void run() { - beast::setCurrentThreadName("Resource::Manager"); + this_thread::set_name("Resrc::Manager"); for (;;) { logic_.periodicActivity(); diff --git a/src/test/beast/beast_CurrentThreadName_test.cpp b/src/test/basics/ThreadName_test.cpp similarity index 84% rename from src/test/beast/beast_CurrentThreadName_test.cpp rename to src/test/basics/ThreadName_test.cpp index 653b0a89618..89016274994 100644 --- a/src/test/beast/beast_CurrentThreadName_test.cpp +++ b/src/test/basics/ThreadName_test.cpp @@ -17,6 +17,7 @@ */ //============================================================================== +#include #include #include #include @@ -25,7 +26,7 @@ namespace ripple { namespace test { -class CurrentThreadName_test : public beast::unit_test::suite +class ThreadName_test : public beast::unit_test::suite { private: static void @@ -34,26 +35,19 @@ class CurrentThreadName_test : public beast::unit_test::suite std::atomic* stop, std::atomic* state) { - // Verify that upon creation a thread has no name. - auto const initialThreadName = beast::getCurrentThreadName(); - // Set the new name. - beast::setCurrentThreadName(myName); + this_thread::set_name(myName); // Indicate to caller that the name is set. *state = 1; - // If there is an initial thread name then we failed. - if (!initialThreadName.empty()) - return; - // Wait until all threads have their names. while (!*stop) ; // Make sure the thread name that we set before is still there // (not overwritten by, for instance, another thread). - if (beast::getCurrentThreadName() == myName) + if (this_thread::get_name() == myName) *state = 2; } @@ -86,7 +80,7 @@ class CurrentThreadName_test : public beast::unit_test::suite } }; -BEAST_DEFINE_TESTSUITE(CurrentThreadName, core, beast); +BEAST_DEFINE_TESTSUITE(ThreadName, basics, ripple); } // namespace test } // namespace ripple diff --git a/src/test/overlay/short_read_test.cpp b/src/test/overlay/short_read_test.cpp index 0efc49b84e3..011c4ef5f78 100644 --- a/src/test/overlay/short_read_test.cpp +++ b/src/test/overlay/short_read_test.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -629,7 +630,7 @@ class short_read_test : public beast::unit_test::suite short_read_test() : work_(io_context_.get_executor()) , thread_(std::thread([this]() { - beast::setCurrentThreadName("io_context"); + this_thread::set_name("io_context"); this->io_context_.run(); })) , context_(make_SSLContext("")) diff --git a/src/xrpld/app/ledger/detail/LedgerCleaner.cpp b/src/xrpld/app/ledger/detail/LedgerCleaner.cpp index 27322e302cc..21434bffdd7 100644 --- a/src/xrpld/app/ledger/detail/LedgerCleaner.cpp +++ b/src/xrpld/app/ledger/detail/LedgerCleaner.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include @@ -218,7 +219,7 @@ class LedgerCleanerImp : public LedgerCleaner void run() { - beast::setCurrentThreadName("LedgerCleaner"); + this_thread::set_name("LedgerCleaner"); JLOG(j_.debug()) << "Started"; while (true) diff --git a/src/xrpld/app/main/BasicApp.cpp b/src/xrpld/app/main/BasicApp.cpp index 504309d0838..f2b3e7c93bc 100644 --- a/src/xrpld/app/main/BasicApp.cpp +++ b/src/xrpld/app/main/BasicApp.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include BasicApp::BasicApp(std::size_t numberOfThreads) @@ -28,7 +29,7 @@ BasicApp::BasicApp(std::size_t numberOfThreads) while (numberOfThreads--) { threads_.emplace_back([this, numberOfThreads]() { - beast::setCurrentThreadName( + ripple::this_thread::set_name( "io svc #" + std::to_string(numberOfThreads)); this->io_service_.run(); }); diff --git a/src/xrpld/app/main/GRPCServer.cpp b/src/xrpld/app/main/GRPCServer.cpp index 7dc4d03b2c2..e4d98583637 100644 --- a/src/xrpld/app/main/GRPCServer.cpp +++ b/src/xrpld/app/main/GRPCServer.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include @@ -600,7 +601,7 @@ GRPCServer::start() { thread_ = std::thread([this]() { // Start the event loop and begin handling requests - beast::setCurrentThreadName("rippled: grpc"); + this_thread::set_name("rippled: grpc"); this->impl_.handleRpcs(); }); } diff --git a/src/xrpld/app/main/LoadManager.cpp b/src/xrpld/app/main/LoadManager.cpp index 01b96a3d26c..65b8d96fa98 100644 --- a/src/xrpld/app/main/LoadManager.cpp +++ b/src/xrpld/app/main/LoadManager.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -101,7 +102,7 @@ LoadManager::stop() void LoadManager::run() { - beast::setCurrentThreadName("LoadManager"); + this_thread::set_name("LoadManager"); using namespace std::chrono_literals; using clock_type = std::chrono::steady_clock; diff --git a/src/xrpld/app/main/Main.cpp b/src/xrpld/app/main/Main.cpp index 6e92c2e83a7..f759893f21a 100644 --- a/src/xrpld/app/main/Main.cpp +++ b/src/xrpld/app/main/Main.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -352,8 +353,7 @@ run(int argc, char** argv) { using namespace std; - beast::setCurrentThreadName( - "rippled: main " + BuildInfo::getVersionString()); + this_thread::set_name("main " + BuildInfo::getVersionString()); po::variables_map vm; @@ -844,7 +844,7 @@ run(int argc, char** argv) } // We have an RPC command to process: - beast::setCurrentThreadName("rippled: rpc"); + this_thread::set_name("rippled: rpc"); return RPCCall::fromCommandLine( *config, vm["parameters"].as>(), *logs); // LCOV_EXCL_STOP diff --git a/src/xrpld/app/misc/SHAMapStoreImp.cpp b/src/xrpld/app/misc/SHAMapStoreImp.cpp index e2e0e3b9c46..cf92e276b72 100644 --- a/src/xrpld/app/misc/SHAMapStoreImp.cpp +++ b/src/xrpld/app/misc/SHAMapStoreImp.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -265,7 +266,7 @@ SHAMapStoreImp::copyNode(std::uint64_t& nodeCount, SHAMapTreeNode const& node) void SHAMapStoreImp::run() { - beast::setCurrentThreadName("SHAMapStore"); + this_thread::set_name("SHAMapStore"); LedgerIndex lastRotated = state_db_.getState().lastRotated; netOPs_ = &app_.getOPs(); ledgerMaster_ = &app_.getLedgerMaster(); diff --git a/src/xrpld/core/detail/Job.cpp b/src/xrpld/core/detail/Job.cpp index 17f600a4f41..478da846a16 100644 --- a/src/xrpld/core/detail/Job.cpp +++ b/src/xrpld/core/detail/Job.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include @@ -61,7 +62,7 @@ Job::queue_time() const void Job::doJob() { - beast::setCurrentThreadName("doJob: " + mName); + this_thread::set_name("doJob: " + mName); m_loadEvent->start(); m_loadEvent->setName(mName); diff --git a/src/xrpld/core/detail/Workers.cpp b/src/xrpld/core/detail/Workers.cpp index 7286f378e85..e2c688e2d42 100644 --- a/src/xrpld/core/detail/Workers.cpp +++ b/src/xrpld/core/detail/Workers.cpp @@ -19,6 +19,7 @@ #include #include +#include #include #include @@ -208,7 +209,7 @@ Workers::Worker::run() for (;;) { // Put the name back in case the callback changed it - beast::setCurrentThreadName(threadName_); + this_thread::set_name(threadName_); // Acquire a task or "internal task." // @@ -261,7 +262,7 @@ Workers::Worker::run() } // Set inactive thread name. - beast::setCurrentThreadName("(" + threadName_ + ")"); + this_thread::set_name("(" + threadName_ + ")"); // [1] We will be here when the paused list is popped // diff --git a/src/xrpld/nodestore/backend/RocksDBFactory.cpp b/src/xrpld/nodestore/backend/RocksDBFactory.cpp index 2034128949f..145814a440b 100644 --- a/src/xrpld/nodestore/backend/RocksDBFactory.cpp +++ b/src/xrpld/nodestore/backend/RocksDBFactory.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -67,7 +68,7 @@ class RocksDBEnv : public rocksdb::EnvWrapper std::size_t const id(++n); std::stringstream ss; ss << "rocksdb #" << id; - beast::setCurrentThreadName(ss.str()); + this_thread::set_name(ss.str()); (*f)(a); } diff --git a/src/xrpld/nodestore/detail/Database.cpp b/src/xrpld/nodestore/detail/Database.cpp index 7564ca60b52..3f7bc84e67c 100644 --- a/src/xrpld/nodestore/detail/Database.cpp +++ b/src/xrpld/nodestore/detail/Database.cpp @@ -18,6 +18,7 @@ //============================================================================== #include +#include #include #include #include @@ -56,8 +57,7 @@ Database::Database( [this](int i) { runningThreads_++; - beast::setCurrentThreadName( - "db prefetch #" + std::to_string(i)); + this_thread::set_name("prefetch " + std::to_string(i)); decltype(read_) read; diff --git a/src/xrpld/perflog/detail/PerfLogImp.cpp b/src/xrpld/perflog/detail/PerfLogImp.cpp index 559bdb1743c..a49a4ccba70 100644 --- a/src/xrpld/perflog/detail/PerfLogImp.cpp +++ b/src/xrpld/perflog/detail/PerfLogImp.cpp @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -258,7 +259,7 @@ PerfLogImp::openLog() void PerfLogImp::run() { - beast::setCurrentThreadName("perflog"); + this_thread::set_name("perflog"); lastLog_ = system_clock::now(); while (true)