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