From f53b8200613ca440b6aec6ef5951d975db46160d Mon Sep 17 00:00:00 2001 From: David CARLIER Date: Sat, 15 Jul 2023 07:34:49 +0100 Subject: [PATCH] thead pool debugging support proposal using native capabilities if possible. --- src/lib/utils/os_utils.cpp | 43 ++++++++++++++++++++-- src/lib/utils/os_utils.h | 8 ++++ src/lib/utils/thread_utils/thread_pool.cpp | 7 +++- 3 files changed, 53 insertions(+), 5 deletions(-) diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp index bab3c776dbf..f96683bc25b 100644 --- a/src/lib/utils/os_utils.cpp +++ b/src/lib/utils/os_utils.cpp @@ -16,16 +16,13 @@ #include #include -#if defined(BOTAN_TARGET_OS_HAS_THREADS) - #include -#endif - #if defined(BOTAN_TARGET_OS_HAS_EXPLICIT_BZERO) #include #endif #if defined(BOTAN_TARGET_OS_HAS_POSIX1) #include + #include #include #include #include @@ -72,6 +69,15 @@ extern "C" char** environ; #include #endif +#if defined(BOTAN_TARGET_IS_FREEBSD) || defined(BOTAN_TARGET_IS_OPENBSD) + #include +#endif + +#if defined(BOTAN_TARGET_OS_HAS_WIN32) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) + #include + #include +#endif + namespace Botan { // Not defined in OS namespace for historical reasons @@ -614,6 +620,35 @@ void OS::page_named(void* page, size_t size) { #endif } +#if defined(BOTAN_TARGET_OS_HAS_THREADS) +void OS::set_thread_name(std::thread& thread, const char* const name) { + int r; + auto hdl = thread.native_handle(); + #if defined(BOTAN_TARGET_OS_IS_LINUX) + r = pthread_setname_np(hdl, name); + #elif defined(BOTAN_TARGET_OS_IS_FREEBSD) + r = pthread_set_name_np(hdl, name); + #elif defined(BOTAN_TARGET_OS_IS_OPENBSD) + r = pthread_set_name_np(hdl, const_cast(name)); + #elif defined(BOTAN_TARGET_OS_IS_NETBSD) + r = pthread_set_name_np(hdl, "%s", const_cast(name)); + #elif defined(BOTAN_TARGET_OS_HAS_WIN32) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) + // This approach (as opposed to trigger an exception) is simpler + // also gives a chance to be in coredumps. + wchar_t val[16]; + if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name, -1, val, 16) > 0) { + r = SetThreadDescription(hdl, val); + } + #else + // TODO other possible oses ? + // macOs does not seem to allow to name threads other than the current one. + BOTAN_UNUSED(hdl); + BOTAN_UNUSED(name); + #endif + BOTAN_UNUSED(r); +} +#endif + #if defined(BOTAN_TARGET_OS_HAS_POSIX1) && !defined(BOTAN_TARGET_OS_IS_EMSCRIPTEN) namespace { diff --git a/src/lib/utils/os_utils.h b/src/lib/utils/os_utils.h index 85bf8407c29..754456b5d37 100644 --- a/src/lib/utils/os_utils.h +++ b/src/lib/utils/os_utils.h @@ -13,6 +13,10 @@ #include #include +#if defined(BOTAN_TARGET_OS_HAS_THREADS) + #include +#endif + namespace Botan::OS { /* @@ -148,6 +152,10 @@ void page_allow_access(void* page); */ void page_named(void* page, size_t size); +#if defined(BOTAN_TARGET_OS_HAS_THREADS) +void set_thread_name(std::thread& thread, const char* const name); +#endif + /** * Run a probe instruction to test for support for a CPU instruction. * Runs in system-specific env that catches illegal instructions; this diff --git a/src/lib/utils/thread_utils/thread_pool.cpp b/src/lib/utils/thread_utils/thread_pool.cpp index d12eb874541..3243f3445e0 100644 --- a/src/lib/utils/thread_utils/thread_pool.cpp +++ b/src/lib/utils/thread_utils/thread_pool.cpp @@ -41,6 +41,8 @@ Thread_Pool& Thread_Pool::global_instance() { Thread_Pool::Thread_Pool(std::optional opt_pool_size) { m_shutdown = false; + // On Linux, it is 16 length max, including terminator + static constexpr char tname[] = "Botan thread"; if(!opt_pool_size.has_value()) { return; @@ -65,8 +67,11 @@ Thread_Pool::Thread_Pool(std::optional opt_pool_size) { } } + m_workers.resize(pool_size); + for(size_t i = 0; i != pool_size; ++i) { - m_workers.push_back(std::thread(&Thread_Pool::worker_thread, this)); + m_workers[i] = std::thread(&Thread_Pool::worker_thread, this); + OS::set_thread_name(m_workers[i], tname); } }