diff --git a/cpp/include/kvikio/defaults.hpp b/cpp/include/kvikio/defaults.hpp index 53f97599f9..62eaa5722d 100644 --- a/cpp/include/kvikio/defaults.hpp +++ b/cpp/include/kvikio/defaults.hpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2022-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -121,7 +121,7 @@ std::tuple getenv_or( */ class defaults { private: - ThreadPool _thread_pool{get_num_threads_from_env()}; + ThreadPool _thread_pool{get_num_threads_from_env(), make_thread_pool_init_task("kvikio")}; CompatMode _compat_mode; std::size_t _task_size; std::size_t _gds_threshold; diff --git a/cpp/include/kvikio/threadpool_wrapper.hpp b/cpp/include/kvikio/threadpool_wrapper.hpp index d0e8d4b286..b036c419e4 100644 --- a/cpp/include/kvikio/threadpool_wrapper.hpp +++ b/cpp/include/kvikio/threadpool_wrapper.hpp @@ -1,12 +1,21 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2025, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ #pragma once +#include +#include +#include +#include +#include +#include + #include +#include + namespace kvikio { /** @@ -14,4 +23,36 @@ namespace kvikio { */ using ThreadPool = BS::thread_pool; +/** + * @brief Build a `BS::thread_pool` init task that names each worker thread. + * + * The returned functor is intended to be passed to `BS::thread_pool`'s + * constructor or `reset()` overloads that accept an `init_task`. It runs + * once per worker as the pool starts each thread, setting the OS-level + * thread name (`comm` on Linux) to `"-"` so profilers such + * as nsys, `top -H`, and `/proc//task//comm` show meaningful + * names instead of the parent process name. + * + * The per-thread index is assigned via an atomic counter captured by the + * returned functor, so different pools can share the same prefix without + * colliding. + * + * Linux caps thread names at 15 characters plus NUL, so keep @p prefix + * short (typically 10 characters or fewer). + * + * @param prefix Name prefix, e.g. `"kvikio"` or `"kvikio-dev"`. + * @return An init task suitable for `BS::thread_pool`. + */ +[[nodiscard]] inline std::function make_thread_pool_init_task(std::string prefix) +{ + auto counter = std::make_shared>(0); + return [counter = std::move(counter), prefix = std::move(prefix)]() { + unsigned int const idx = counter->fetch_add(1, std::memory_order_relaxed); + // Linux comm limit is 15 chars + NUL. + std::array name{}; + std::snprintf(name.data(), name.size(), "%s-%u", prefix.c_str(), idx); + pthread_setname_np(pthread_self(), name.data()); + }; +} + } // namespace kvikio diff --git a/cpp/src/defaults.cpp b/cpp/src/defaults.cpp index fdcaf0d746..6b27f12ccc 100644 --- a/cpp/src/defaults.cpp +++ b/cpp/src/defaults.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2025-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -18,6 +18,7 @@ #include #include #include +#include #include namespace kvikio { @@ -220,7 +221,7 @@ void defaults::set_thread_pool_nthreads(unsigned int nthreads) { KVIKIO_EXPECT( nthreads > 0, "number of threads must be a positive integer", std::invalid_argument); - thread_pool().reset(nthreads); + thread_pool().reset(nthreads, make_thread_pool_init_task("kvikio")); } unsigned int defaults::num_threads() { return thread_pool_nthreads(); } diff --git a/cpp/src/file_handle.cpp b/cpp/src/file_handle.cpp index f058276fe2..edd5b7b7dd 100644 --- a/cpp/src/file_handle.cpp +++ b/cpp/src/file_handle.cpp @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION. + * SPDX-FileCopyrightText: Copyright (c) 2024-2026, NVIDIA CORPORATION & AFFILIATES. All rights reserved. * SPDX-License-Identifier: Apache-2.0 */ @@ -80,7 +80,8 @@ ThreadPool* get_thread_pool_per_block_device(std::string const& file_path) } // First file on this block device: create a new dedicated thread pool - auto thread_pool = std::make_shared(defaults::num_threads()); + auto thread_pool = std::make_shared(defaults::num_threads(), + make_thread_pool_init_task("kvikio-dev")); dev_id_to_thread_pool_map.emplace(block_dev_info.id, thread_pool); file_path_to_thread_pool_map.emplace(file_path, thread_pool); return thread_pool.get();