GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 100.0% 5 / 0 / 5
Functions: 100.0% 1 / 0 / 1
Branches: -% 0 / 0 / 0

libs/capy/src/detail/thread_name.cpp
Line Branch Exec Source
1 //
2 // Copyright (c) 2026 Michael Vandeberg
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/capy
8 //
9
10 #include <boost/capy/detail/thread_name.hpp>
11
12 #if defined(_WIN32)
13
14 #ifndef NOMINMAX
15 #define NOMINMAX
16 #endif
17 #include <windows.h>
18 #include <string>
19
20 #elif defined(__APPLE__)
21
22 #include <pthread.h>
23 #include <cstring>
24
25 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
26
27 #include <pthread.h>
28 #include <cstring>
29
30 #endif
31
32 /*
33 Platform-specific thread naming implementation.
34
35 Each platform has a different API and name length limit:
36 - Windows: SetThreadDescription with UTF-8 to UTF-16 conversion (no limit)
37 - macOS: pthread_setname_np(name) with 63-char limit
38 - Linux/BSD: pthread_setname_np(thread, name) with 15-char limit
39
40 All operations are best-effort and silently fail on error, since thread
41 naming is purely for debugging visibility and should never affect program
42 correctness. The noexcept guarantee is maintained by catching exceptions
43 from std::wstring allocation on Windows.
44 */
45
46 namespace boost {
47 namespace capy {
48 namespace detail {
49
50 void
51 39 set_current_thread_name(char const* name) noexcept
52 {
53 #if defined(_WIN32)
54 // SetThreadDescription requires Windows 10 1607+. Older Windows versions
55 // are unsupported; the program may fail to link on those systems.
56
57 // Query required buffer size for UTF-8 to wide conversion.
58 int required = MultiByteToWideChar(CP_UTF8, 0, name, -1, nullptr, 0);
59 if(required <= 0)
60 return;
61
62 // Allocate and convert; catch exceptions to maintain noexcept.
63 std::wstring wname;
64 try
65 {
66 wname.resize(static_cast<std::size_t>(required));
67 }
68 catch(...)
69 {
70 return;
71 }
72
73 if(MultiByteToWideChar(CP_UTF8, 0, name, -1, wname.data(), required) <= 0)
74 return;
75
76 // Ignore return value: thread naming is best-effort for debugging.
77 (void)SetThreadDescription(GetCurrentThread(), wname.c_str());
78 #elif defined(__APPLE__)
79 // macOS pthread_setname_np takes only the name (no thread handle)
80 // and has a 64 char limit (63 + null terminator)
81 char truncated[64];
82 std::strncpy(truncated, name, 63);
83 truncated[63] = '\0';
84
85 // Ignore return value: thread naming is best-effort for debugging.
86 (void)pthread_setname_np(truncated);
87 #elif defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
88 // pthread_setname_np has 16 char limit (15 + null terminator)
89 char truncated[16];
90 39 std::strncpy(truncated, name, 15);
91 39 truncated[15] = '\0';
92
93 // Ignore return value: thread naming is best-effort for debugging.
94 39 (void)pthread_setname_np(pthread_self(), truncated);
95 #else
96 (void)name;
97 #endif
98 39 }
99
100 } // detail
101 } // capy
102 } // boost
103