On 7/02/2020 4:07 am, Gaisbauer, Markus wrote:
> Hi,
>
> I am looking for a sponsor who could create a ticket for the following proposal:
>
> Microsoft recently introduced a new API to assign a name to native Windows threads.
> https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
>
> These thread names can be shown by debuggers, C++ profilers, etc. The new API is available since either Windows 10 1607 or Windows Server 2016.
>
> The JVM already tries to set a native thread name both for all internal JVM threads and all Java threads (except main).
>
> But the Windows implementation of os::set_native_thread_name currently uses a weird hack described here.
> https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2015&redirectedfrom=MSDN
>
> For this hack, debugger has to be already attached when a thread starts.
>
> I propose to check in os::set_native_thread_name if SetThreadDescription is available. If yes, either call it instead or in addition to the current code.
>
> Here is some prototype code that worked for me:
>
> typedef HRESULT(WINAPI *SetThreadDescriptionT)(HANDLE, PCWSTR);
>
> static SetThreadDescriptionT getSetThreadDescriptionT() {
> HMODULE kernel32 = GetModuleHandle("Kernel32.dll");
> return kernel32 ? reinterpret_cast<SetThreadDescriptionT>(GetProcAddress(kernel32, "SetThreadDescription")) : nullptr;
> }
>
> static LPWSTR utf8_decode(const char *name) {
> if (name == nullptr) return nullptr;
> int name_len = (int) strlen(name);
> int size_needed = MultiByteToWideChar(CP_UTF8, 0, name, name_len, NULL, 0);
> size_t buffer_len = sizeof(wchar_t) * (size_needed + 1);
> LPWSTR result = (LPWSTR) os::malloc(buffer_len, mtInternal);
> memset(result, 0, buffer_len);
> MultiByteToWideChar(CP_UTF8, 0, name, name_len, result, size_needed);
> return result;
> }
>
> void os::set_native_thread_name(const char *name) {
>
> // First try calling SetThreadDescription available since Windows 10 1607 / Windows Server 2016
> // See: https://docs.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-setthreaddescription
>
> static SetThreadDescriptionT SetThreadDescription = getSetThreadDescriptionT();
> if (SetThreadDescription) {
> LPWSTR nameWide = utf8_decode(name);
> if (nameWide != nullptr) {
> SetThreadDescription(GetCurrentThread(), nameWide);
> os::free(nameWide);
> }
> return;
> }
>
> // fallback
> ...
> }
>
> Best regards,
> Markus