9 #include "quill/core/Attributes.h" 10 #include "quill/core/QuillError.h" 18 #if !defined(WIN32_LEAN_AND_MEAN) 19 #define WIN32_LEAN_AND_MEAN 22 #if !defined(NOMINMAX) 31 #elif defined(__APPLE__) 32 #include <mach/thread_act.h> 33 #include <mach/thread_policy.h> 35 #elif defined(__NetBSD__) 39 #elif defined(__FreeBSD__) 40 #include <pthread_np.h> 43 #elif defined(__DragonFly__) 44 #include <pthread_np.h> 47 #elif defined(__OpenBSD__) 48 #include <pthread_np.h> 53 #include <sys/syscall.h> 61 #if defined(_WIN32) && defined(_MSC_VER) 68 QUILL_NODISCARD
inline std::wstring s2ws(std::string
const& str) noexcept
71 #pragma warning(disable : 4996) 73 using convert_t = std::codecvt_utf8_utf16<wchar_t>;
74 std::wstring_convert<convert_t, wchar_t> converter;
75 return converter.from_bytes(str);
85 QUILL_NODISCARD
inline std::string ws2s(std::wstring
const& wstr) noexcept
88 #pragma warning(disable : 4996) 90 using convert_t = std::codecvt_utf8_utf16<wchar_t>;
91 std::wstring_convert<convert_t, wchar_t> converter;
92 return converter.to_bytes(wstr);
98 template <
typename ReturnT,
typename Signature,
typename... Args>
99 ReturnT callRunTimeDynamicLinkedFunction(std::string
const& dll_name,
100 std::string
const& function_name, Args... args)
107 const HINSTANCE hinstLibrary = LoadLibraryW(s2ws(dll_name).c_str());
109 const HINSTANCE hinstLibrary = LoadLibraryA(dll_name.c_str());
112 if (QUILL_UNLIKELY(hinstLibrary ==
nullptr))
114 QUILL_THROW(
QuillError{std::string{
"Failed to load library " + dll_name}});
118 FARPROC proc_address = GetProcAddress(hinstLibrary, function_name.c_str());
120 if (QUILL_UNLIKELY(proc_address ==
nullptr))
122 FreeLibrary(hinstLibrary);
123 QUILL_THROW(
QuillError{std::string{
"Failed to call " + function_name +
" " + dll_name}});
128 std::memcpy(&callable, &proc_address,
sizeof(proc_address));
130 ReturnT
const hr = callable(static_cast<Args&&>(args)...);
131 BOOL
const fFreeResult = FreeLibrary(hinstLibrary);
133 if (QUILL_UNLIKELY(!fFreeResult))
135 QUILL_THROW(
QuillError{std::string{
"Failed to free library " + dll_name}});
148 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline std::string
get_thread_name()
150 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__ANDROID__) || \ 151 defined(QUILL_NO_THREAD_NAME_SUPPORT) 153 return std::string{
"ThreadNameDisabled"};
154 #elif defined(_WIN32) 155 PWSTR data =
nullptr;
157 typedef HRESULT(WINAPI * GetThreadDescriptionSignature)(HANDLE, PWSTR*);
158 HRESULT hr = callRunTimeDynamicLinkedFunction<HRESULT, GetThreadDescriptionSignature>(
159 "KernelBase.dll",
"GetThreadDescription", GetCurrentThread(), &data);
163 QUILL_THROW(
QuillError{
"Failed to get thread name"});
166 if (QUILL_UNLIKELY(data ==
nullptr))
168 QUILL_THROW(
QuillError{
"Failed to get thread name. Invalid data."});
171 std::wstring
const wide_name{data, wcsnlen_s(data, 256)};
173 return ws2s(wide_name);
176 char thread_name[16] = {
'\0'};
177 #if defined(__OpenBSD__) || defined(__FreeBSD__) 178 pthread_get_name_np(pthread_self(), &thread_name[0], 16);
180 auto res = pthread_getname_np(pthread_self(), &thread_name[0], 16);
183 QUILL_THROW(
QuillError{
"Failed to get thread name. error: " + std::to_string(res)});
186 return std::string{&thread_name[0], strlen(&thread_name[0])};
190 #if defined(QUILL_USE_SEQUENTIAL_THREAD_ID) 191 extern std::atomic<uint32_t> g_next_thread_id;
198 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline uint32_t
get_thread_id() noexcept
200 #if defined(QUILL_USE_SEQUENTIAL_THREAD_ID) 201 return g_next_thread_id.fetch_add(1u) + 1u;
202 #elif defined(__CYGWIN__) 205 #elif defined(_WIN32) 206 return static_cast<uint32_t
>(GetCurrentThreadId());
207 #elif defined(__linux__) 208 return static_cast<uint32_t
>(::syscall(SYS_gettid));
209 #elif defined(__APPLE__) 211 pthread_threadid_np(
nullptr, &tid64);
212 return static_cast<uint32_t
>(tid64);
213 #elif defined(__NetBSD__) 214 return static_cast<uint32_t
>(_lwp_self());
215 #elif defined(__FreeBSD__) 218 return static_cast<uint32_t
>(lwpid);
219 #elif defined(__DragonFly__) 220 return static_cast<uint32_t
>(lwp_gettid());
221 #elif defined(__OpenBSD__) 222 return static_cast<uint32_t
>(getthrid());
224 return reinterpret_cast<uintptr_t
>(pthread_self());
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED std::string get_thread_name()
Returns the name of the thread.
Definition: ThreadUtilities.h:148
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:24
custom exception
Definition: QuillError.h:45
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED uint32_t get_thread_id() noexcept
Returns the os assigned ID of the thread.
Definition: ThreadUtilities.h:198