-
Notifications
You must be signed in to change notification settings - Fork 564
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
thead pool debugging support proposal using native capabilities if po… #3628
Conversation
b91f69d
to
f53b820
Compare
src/lib/utils/os_utils.cpp
Outdated
#if defined(BOTAN_TARGET_OS_IS_LINUX) | ||
r = pthread_setname_np(hdl, name); | ||
#elif defined(BOTAN_TARGET_OS_IS_FREEBSD) | ||
r = pthread_set_name_np(hdl, name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
FreeBSD also seems to support pthead_setname_np
(https://man.freebsd.org/cgi/man.cgi?query=pthread_set_name_np) which would reduce the number of conditionals.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we consider windows the only exception in term of supporting EOL releases then yes.
src/lib/utils/os_utils.h
Outdated
@@ -148,6 +152,10 @@ void page_allow_access(void* page); | |||
*/ | |||
void page_named(void* page, size_t size); | |||
|
|||
#if defined(BOTAN_TARGET_OS_HAS_THREADS) | |||
void set_thread_name(std::thread& thread, const char* const name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it required (by any OS) that this point to static storage? If so that should be documented here. Otherwise, name
should be a const std::string&
instead of a C style string.
(I would say a std::string_view
but you can't convert that to a NULL terminated string)
src/lib/utils/os_utils.cpp
Outdated
#elif defined(BOTAN_TARGET_OS_IS_FREEBSD) | ||
r = pthread_set_name_np(hdl, name); | ||
#elif defined(BOTAN_TARGET_OS_IS_OPENBSD) | ||
r = pthread_set_name_np(hdl, const_cast<char*>(name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This cast doesn't seem to be necessary? (https://man.openbsd.org/pthread_set_name_np)
src/lib/utils/os_utils.cpp
Outdated
#elif defined(BOTAN_TARGET_OS_IS_OPENBSD) | ||
r = pthread_set_name_np(hdl, const_cast<char*>(name)); | ||
#elif defined(BOTAN_TARGET_OS_IS_NETBSD) | ||
r = pthread_set_name_np(hdl, "%s", const_cast<char*>(name)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What a weird interface
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fair point, you end up 99% of the time with a string anyway..
src/lib/utils/os_utils.cpp
Outdated
// also gives a chance to be in coredumps. | ||
wchar_t val[16]; | ||
if(MultiByteToWideChar(CP_UTF8, MB_ERR_INVALID_CHARS, name, -1, val, 16) > 0) { | ||
r = SetThreadDescription(hdl, val); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIUC https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription this function is only supported on Windows 10 or higher, which I think would be problematic
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general the policy is that we don't support operating systems that are no longer supported by the OS vendor, but for Windows we are basically forced to be more lax than that simply due to the huge installed base of out of date systems.
I think practically speaking we are limited to using features that are available in the oldest version of Windows that is supported by the oldest version of VC++ we support. For VC that's VC2022 now. But I can't find anything definite about the oldest OS that VC2022 will allow you to target. I know we reverted #365 because people were still building XP-compatible binaries in 2016.
src/lib/utils/os_utils.cpp
Outdated
int r; | ||
auto hdl = thread.native_handle(); | ||
#if defined(BOTAN_TARGET_OS_IS_LINUX) | ||
r = pthread_setname_np(hdl, name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of assigning to r
and then using BOTAN_UNUSED
later on in the function just static_cast<void>(pthread_set...)
within each block.
src/lib/utils/os_utils.cpp
Outdated
#if defined(BOTAN_TARGET_OS_HAS_THREADS) | ||
void OS::set_thread_name(std::thread& thread, const char* const name) { | ||
int r; | ||
auto hdl = thread.native_handle(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::thread::native_handle
isn't necessarily guaranteed to exist, which would cause this to fail to compile on a (probably weird) OS that supported threads but didn't let you access native handles.
Instead call thread.native_handle()
within each block which ensures we only call it if we have some idea what OS we are on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah right I thought HAS_THREADS meant "all the way", fair enough then.
4229e6b
to
02fb333
Compare
src/lib/utils/os_utils.cpp
Outdated
#elif defined(BOTAN_TARGET_OS_IS_NETBSD) | ||
static_cast<void>(pthread_set_name_np(thread.native_handle(), "%s", const_cast<char*>(name.c_str()))); | ||
#elif defined(BOTAN_TARGET_OS_HAS_WIN32) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) | ||
const DWORD MS_VC_EXCEPTION = 0x406D1388; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This approach doesn't seem so useful since it's works if you are currently attached to a debugger.
If it's possible to check at compile time what the target OS is, I'd suggest calling the Windows 10 function if it is available and for older systems just do nothing. If that's not possible I'd say just remove this block entirely and leave a comment that we can use SetThreadDescription
in the future.
In 33dee2f I deprecated support for older Windows but we'll probably want to wait at least a release or two before pulling the trigger on it.
02fb333
to
7fe391f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! This is looking very good now. I left a few comments.
src/lib/utils/os_utils.h
Outdated
@@ -148,6 +152,10 @@ void page_allow_access(void* page); | |||
*/ | |||
void page_named(void* page, size_t size); | |||
|
|||
#if defined(BOTAN_TARGET_OS_HAS_THREADS) | |||
void set_thread_name(std::thread& thread, std::string& name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I guess name
cannot be a string_view
since we need to get the null terminated value, so I think it should be a const std::string&
@@ -41,6 +41,8 @@ Thread_Pool& Thread_Pool::global_instance() { | |||
|
|||
Thread_Pool::Thread_Pool(std::optional<size_t> opt_pool_size) { | |||
m_shutdown = false; | |||
// On Linux, it is 16 length max, including terminator | |||
std::string tname = "Botan thread"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be const
#elif defined(BOTAN_TARGET_OS_IS_NETBSD) | ||
static_cast<void>(pthread_set_name_np(thread.native_handle(), "%s", const_cast<char*>(name.c_str()))); | ||
#elif defined(BOTAN_TARGET_OS_HAS_WIN32) && defined(BOTAN_BUILD_COMPILER_IS_MSVC) | ||
// Using SetThreadDescription from Win10 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There should be a BOTAN_UNUSED
here as well - currently Windows CI is failing because the parameters are not used
src/lib/utils/os_utils.cpp
Outdated
// TODO other possible oses ? | ||
// macOs does not seem to allow to name threads other than the current one. | ||
BOTAN_UNUSED(thread); | ||
BOTAN_UNUSED(name); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can pass multiple args to a single invocation of BOTAN_UNUSED
- BOTAN_UNUSED(thread, name)
7fe391f
to
313e439
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great. Thanks for addressing the review comments.
…ssible.