Cbeam
Loading...
Searching...
No Matches
thread.hpp
Go to the documentation of this file.
1/*
2Copyright (c) 2025 acrion innovations GmbH
3Authors: Stefan Zipproth, s.zipproth@acrion.ch
4
5This file is part of Cbeam, see https://github.com/acrion/cbeam and https://cbeam.org
6
7Cbeam is offered under a commercial and under the AGPL license.
8For commercial licensing, contact us at https://acrion.ch/sales. For AGPL licensing, see below.
9
10AGPL licensing:
11
12Cbeam is free software: you can redistribute it and/or modify
13it under the terms of the GNU Affero General Public License as published by
14the Free Software Foundation, either version 3 of the License, or
15(at your option) any later version.
16
17Cbeam is distributed in the hope that it will be useful,
18but WITHOUT ANY WARRANTY; without even the implied warranty of
19MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20GNU Affero General Public License for more details.
21
22You should have received a copy of the GNU Affero General Public License
23along with Cbeam. If not, see <https://www.gnu.org/licenses/>.
24*/
25
26#pragma once
27
28#include <cbeam/convert/string.hpp> // for cbeam::convert::from_string
29
30#include <cstddef> // for std::size_t
31
32#include <iomanip> // for std::operator<<, std::setfill, std::setw
33#include <sstream> // for std::basic_ostream, std::hex, std::uppercase, std::wstringstream
34#include <string> // for allocator, wstring
35#include <thread>
36
37#ifdef _WIN32
39#else
40 #include <pthread.h> // for pthread_getname_np, pthread_t
41
42 #ifdef __linux__
43 #include <sys/prctl.h>
44 #endif
45#endif
46
47namespace cbeam::concurrency
48{
49#ifdef _WIN32
50 using thread_id_type = HANDLE;
51#else
52 using thread_id_type = pthread_t;
53#endif
54
64 {
65#ifdef _WIN32
66 return GetCurrentThread();
67#else
68 return pthread_self();
69#endif
70 }
71
72#ifdef _WIN32
73 #pragma pack(push, 8)
74 typedef struct tagTHREADNAME_INFO
75 {
76 DWORD dwType; // Must be 0x1000.
77 LPCSTR szName; // Pointer to name (in user addr space).
78 DWORD dwThreadID; // Thread ID (-1=caller thread).
79 DWORD dwFlags; // Reserved for future use, must be zero.
81 #pragma pack(pop)
82
92 inline void set_thread_name(uint32_t dwThreadID, const char* thread_name)
93 {
94 const DWORD MS_VC_EXCEPTION = 0x406D1388;
95 THREADNAME_INFO info;
96 info.dwType = 0x1000;
97 info.szName = thread_name;
98 info.dwThreadID = dwThreadID;
99 info.dwFlags = 0;
100
101 __try
102 {
103 RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR), (ULONG_PTR*)&info);
104 }
105 __except (EXCEPTION_EXECUTE_HANDLER)
106 {
107 }
108 }
109
115 inline void set_thread_name(const char* thread_name)
116 {
117 set_thread_name(GetCurrentThreadId(), thread_name);
118 }
119
126 inline void set_thread_name(std::thread& thread, const char* thread_name)
127 {
128 DWORD thread_id = ::GetThreadId(static_cast<HANDLE>(thread.native_handle()));
129 set_thread_name(thread_id, thread_name);
130 }
131#elif defined(__APPLE__)
141 inline void set_thread_name(std::thread& thread, const char* thread_name)
142 {
143 // not possible under darwin
144 }
145
151 inline void set_thread_name(const char* thread_name)
152 {
153 pthread_setname_np(thread_name);
154 }
155#else
162 inline void set_thread_name(std::thread& thread, const char* thread_name)
163 {
164 pthread_setname_np(thread.native_handle(), thread_name);
165 }
166
172 inline void set_thread_name(const char* thread_name)
173 {
174 prctl(PR_SET_NAME, thread_name, 0, 0, 0);
175 }
176#endif
177
184 inline std::wstring get_thread_name(thread_id_type id)
185 {
186#ifdef _WIN32
187 PWSTR data;
188 HRESULT hr = GetThreadDescription(id, &data);
189 if (SUCCEEDED(hr))
190 {
191 std::wstring str(data);
192 LocalFree(data);
193 return str;
194 }
195#else
196 char thread_name[64];
197 if (pthread_getname_np(id, thread_name, sizeof(thread_name)) == 0)
198 {
199 return convert::from_string<std::wstring>(thread_name);
200 }
201#endif
202 return L"";
203 }
204
214 inline std::wstring to_string(concurrency::thread_id_type id, std::size_t mask = (std::size_t)-1)
215 {
216 std::wstringstream ss;
217
218#if defined(__GNUC__) && (__GNUC__ >= 11) && __linux__
221 std::hash<decltype(id)> hasher;
222 std::size_t hash_value = hasher(id) & mask;
223 ss << std::setfill(L'0') << std::setw(4) << std::hex << std::uppercase << hash_value;
224#else
225 ss << std::setfill(L'0') << std::setw(4) << std::hex << std::uppercase
226 << (reinterpret_cast<std::size_t>(id) & mask);
227#endif
228
229 return ss.str();
230 }
231}
Provides concurrency primitives and abstractions for multithreaded programming. It features the power...
Definition message_manager.hpp:47
HANDLE thread_id_type
Definition thread.hpp:50
thread_id_type get_current_thread_id()
Retrieves the current thread's native identifier.
Definition thread.hpp:63
void set_thread_name(uint32_t dwThreadID, const char *thread_name)
Sets the name for a thread with a specified Thread ID.
Definition thread.hpp:92
struct cbeam::concurrency::tagTHREADNAME_INFO THREADNAME_INFO
std::wstring to_string(concurrency::thread_id_type id, std::size_t mask=(std::size_t) -1)
Returns a hexadecimal string representation of the given thread ID.
Definition thread.hpp:214
std::wstring get_thread_name(thread_id_type id)
Retrieves the name of the specified thread.
Definition thread.hpp:184
std::wstring from_string< std::wstring >(const std::string &str)
Converts the given std::string to std::wstring using UTF-8 to UTF-16 encoding.
Definition string.hpp:196
DWORD dwFlags
Definition thread.hpp:79
DWORD dwThreadID
Definition thread.hpp:78
DWORD dwType
Definition thread.hpp:76
LPCSTR szName
Definition thread.hpp:77
Header file to manage inclusion of windows.h with specific settings.