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) 29 #elif defined(__APPLE__) 30 #include <mach/thread_act.h> 31 #include <mach/thread_policy.h> 33 #elif defined(__NetBSD__) 37 #elif defined(__FreeBSD__) 38 #include <pthread_np.h> 41 #elif defined(__DragonFly__) 42 #include <pthread_np.h> 45 #elif defined(__OpenBSD__) 46 #include <pthread_np.h> 51 #include <sys/syscall.h> 66 QUILL_NODISCARD
inline std::wstring s2ws(std::string
const& str)
70 return std::wstring{};
73 int const size_needed =
74 ::MultiByteToWideChar(CP_UTF8, 0, str.data(),
static_cast<int>(str.size()),
nullptr, 0);
78 return std::wstring{};
81 std::wstring ret_val(static_cast<size_t>(size_needed), 0);
82 ::MultiByteToWideChar(CP_UTF8, 0, str.data(),
static_cast<int>(str.size()), &ret_val[0], size_needed);
91 QUILL_NODISCARD
inline std::string ws2s(std::wstring
const& wstr)
98 int const size_needed = ::WideCharToMultiByte(
99 CP_UTF8, 0, wstr.data(),
static_cast<int>(wstr.size()),
nullptr, 0,
nullptr,
nullptr);
101 if (size_needed == 0)
103 return std::string{};
106 std::string ret_val(static_cast<size_t>(size_needed), 0);
107 ::WideCharToMultiByte(CP_UTF8, 0, wstr.data(),
static_cast<int>(wstr.size()),
108 &ret_val[0], size_needed,
nullptr,
nullptr);
113 template <
typename ReturnT,
typename Signature,
typename... Args>
114 ReturnT callRunTimeDynamicLinkedFunction(std::string
const& dll_name,
115 std::string
const& function_name, Args... args)
121 HMODULE
const hinstLibrary = ::GetModuleHandleA(dll_name.c_str());
123 if (QUILL_UNLIKELY(hinstLibrary ==
nullptr))
125 QUILL_THROW(
QuillError{std::string{
"Failed to get module handle for " + dll_name}});
129 FARPROC proc_address = GetProcAddress(hinstLibrary, function_name.c_str());
131 if (QUILL_UNLIKELY(proc_address ==
nullptr))
133 QUILL_THROW(
QuillError{std::string{
"Failed to call " + function_name +
" " + dll_name}});
138 std::memcpy(&callable, &proc_address,
sizeof(proc_address));
140 return callable(static_cast<Args&&>(args)...);
150 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline std::string
get_thread_name()
152 #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(__ANDROID__) || \ 153 defined(QUILL_NO_THREAD_NAME_SUPPORT) 155 return std::string{
"ThreadNameDisabled"};
156 #elif defined(_WIN32) 157 PWSTR data =
nullptr;
158 typedef HRESULT(WINAPI * GetThreadDescriptionSignature)(HANDLE, PWSTR*);
161 HMODULE
const hinstLibrary = ::GetModuleHandleW(L
"KernelBase.dll");
165 return std::string{
"ThreadNameDisabled"};
168 FARPROC
const proc_address = GetProcAddress(hinstLibrary,
"GetThreadDescription");
172 return std::string{
"ThreadNameDisabled"};
175 GetThreadDescriptionSignature callable;
176 std::memcpy(&callable, &proc_address,
sizeof(proc_address));
178 HRESULT
const hr = callable(GetCurrentThread(), &data);
180 if (FAILED(hr) || QUILL_UNLIKELY(data ==
nullptr))
182 return std::string{
"ThreadNameDisabled"};
185 std::wstring
const wide_name{data, wcsnlen_s(data, 256)};
187 return ws2s(wide_name);
190 char thread_name[16] = {
'\0'};
191 #if defined(__OpenBSD__) || defined(__FreeBSD__) 192 pthread_get_name_np(pthread_self(), &thread_name[0], 16);
194 auto res = pthread_getname_np(pthread_self(), &thread_name[0], 16);
197 QUILL_THROW(
QuillError{
"Failed to get thread name. error: " + std::to_string(res)});
200 return std::string{&thread_name[0], strlen(&thread_name[0])};
204 #if defined(QUILL_USE_SEQUENTIAL_THREAD_ID) 205 extern std::atomic<uint32_t> g_next_thread_id;
206 extern QUILL_THREAD_LOCAL uint32_t g_cached_thread_id;
213 QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED
inline uint32_t
get_thread_id() noexcept
215 #if defined(QUILL_USE_SEQUENTIAL_THREAD_ID) 216 if (QUILL_LIKELY(g_cached_thread_id != 0u))
218 return g_cached_thread_id;
221 g_cached_thread_id = g_next_thread_id.fetch_add(1u, std::memory_order_relaxed) + 1u;
222 return g_cached_thread_id;
223 #elif defined(__CYGWIN__) 226 #elif defined(_WIN32) 227 return static_cast<uint32_t
>(GetCurrentThreadId());
228 #elif defined(__linux__) 229 return static_cast<uint32_t
>(::syscall(SYS_gettid));
230 #elif defined(__APPLE__) 232 pthread_threadid_np(
nullptr, &tid64);
233 return static_cast<uint32_t
>(tid64);
234 #elif defined(__NetBSD__) 235 return static_cast<uint32_t
>(_lwp_self());
236 #elif defined(__FreeBSD__) 239 return static_cast<uint32_t
>(lwpid);
240 #elif defined(__DragonFly__) 241 return static_cast<uint32_t
>(lwp_gettid());
242 #elif defined(__OpenBSD__) 243 return static_cast<uint32_t
>(getthrid());
245 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:150
Setups a signal handler to handle fatal signals.
Definition: BackendManager.h:28
custom exception
Definition: QuillError.h:47
QUILL_NODISCARD QUILL_EXPORT QUILL_ATTRIBUTE_USED uint32_t get_thread_id() noexcept
Returns the os assigned ID of the thread.
Definition: ThreadUtilities.h:213