Line data Source code
1 : // Copyright (c) 2018-2019 The Bitcoin Core developers 2 : // Distributed under the MIT software license, see the accompanying 3 : // file COPYING or http://www.opensource.org/licenses/mit-license.php. 4 : 5 : #if defined(HAVE_CONFIG_H) 6 : #include <config/pivx-config.h> 7 : #endif 8 : 9 : #include <atomic> 10 : #include <thread> 11 : 12 : #if (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) 13 : #include <pthread.h> 14 : #include <pthread_np.h> 15 : #endif 16 : 17 : #include <util/threadnames.h> 18 : 19 : #include "ctpl_stl.h" 20 : #include "utiltime.h" 21 : #include "tinyformat.h" 22 : 23 : #ifdef HAVE_SYS_PRCTL_H 24 : #include <sys/prctl.h> // For prctl, PR_SET_NAME, PR_GET_NAME 25 : #endif 26 : 27 : //! Set the thread's name at the process level. Does not affect the 28 : //! internal name. 29 10597 : static void SetThreadName(const char* name) 30 : { 31 : #if defined(PR_SET_NAME) 32 : // Only the first 15 characters are used (16 - NUL terminator) 33 10597 : ::prctl(PR_SET_NAME, name, 0, 0, 0); 34 : #elif (defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)) 35 : pthread_set_name_np(pthread_self(), name); 36 : #elif defined(MAC_OSX) 37 : pthread_setname_np(name); 38 : #else 39 : // Prevent warnings for unused parameters... 40 : (void)name; 41 : #endif 42 10597 : } 43 : 44 : // If we have thread_local, just keep thread ID and name in a thread_local 45 : // global. 46 : #if defined(HAVE_THREAD_LOCAL) 47 : 48 10597 : static thread_local std::string g_thread_name; 49 0 : const std::string& util::ThreadGetInternalName() { return g_thread_name; } 50 : //! Set the in-memory internal name for this thread. Does not affect the process 51 : //! name. 52 10597 : static void SetInternalName(std::string name) { g_thread_name = std::move(name); } 53 : 54 : // Without thread_local available, don't handle internal name at all. 55 : #else 56 : 57 : static const std::string empty_string; 58 : const std::string& util::ThreadGetInternalName() { return empty_string; } 59 : static void SetInternalName(std::string name) { } 60 : #endif 61 : 62 10597 : void util::ThreadRename(std::string&& name) 63 : { 64 10597 : SetThreadName(("b-" + name).c_str()); 65 21194 : SetInternalName(std::move(name)); 66 10597 : } 67 : 68 0 : void util::ThreadSetInternalName(std::string&& name) 69 : { 70 0 : SetInternalName(std::move(name)); 71 0 : } 72 : 73 348 : void RenameThreadPool(ctpl::thread_pool& tp, const char* baseName) 74 : { 75 348 : auto cond = std::make_shared<std::condition_variable>(); 76 696 : auto mutex = std::make_shared<std::mutex>(); 77 348 : std::atomic<int> doneCnt(0); 78 1740 : for (int i = 0; i < tp.size(); i++) { 79 2784 : tp.push([baseName, i, cond, mutex, &doneCnt](int threadId) { 80 2784 : util::ThreadRename(strprintf("%s-%d", baseName, i).c_str()); 81 1392 : doneCnt++; 82 1392 : std::unique_lock<std::mutex> l(*mutex); 83 1392 : cond->wait(l); 84 1392 : }); 85 : } 86 714 : while (doneCnt != tp.size()) { 87 366 : MilliSleep(10); 88 : } 89 348 : cond->notify_all(); 90 348 : }