Skip to content

Commit 24050bd

Browse files
Support setting thread description
This change adds setting a description for a thread On OSes that support such a feature. This is useful when using a debugger or viewing CPU profiles.
1 parent b793fe4 commit 24050bd

8 files changed

Lines changed: 106 additions & 12 deletions

File tree

lib/Common/Common/Jobs.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,7 +535,14 @@ namespace JsUtil
535535

536536
this->parallelThreadData[i]->processor = this;
537537
// Make sure to create the thread suspended so the thread handle can be assigned before the thread starts running
538-
this->parallelThreadData[i]->threadHandle = reinterpret_cast<HANDLE>(PlatformAgnostic::Thread::Create(0, &StaticThreadProc, this->parallelThreadData[i], PlatformAgnostic::Thread::ThreadInitCreateSuspended));
538+
auto threadHandle = PlatformAgnostic::Thread::Create(0, &StaticThreadProc,
539+
this->parallelThreadData[i], PlatformAgnostic::Thread::ThreadInitCreateSuspended, _u("Chakra Parallel Worker Thread"));
540+
541+
if (threadHandle != PlatformAgnostic::Thread::InvalidHandle)
542+
{
543+
this->parallelThreadData[i]->threadHandle = reinterpret_cast<HANDLE>(threadHandle);
544+
}
545+
539546
if (!this->parallelThreadData[i]->threadHandle)
540547
{
541548
HeapDelete(parallelThreadData[i]);

lib/Common/Core/DelayLoadLibrary.cpp

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,35 @@ bool DelayLoadLibrary::IsAvailable()
5252

5353
#if _WIN32
5454

55+
static Kernel32Library Kernel32LibraryObject;
56+
Kernel32Library* Kernel32Library::Instance = &Kernel32LibraryObject;
57+
58+
LPCTSTR Kernel32Library::GetLibraryName() const
59+
{
60+
return _u("kernel32.dll");
61+
}
62+
63+
HRESULT Kernel32Library::SetThreadDescription(
64+
_In_ HANDLE hThread,
65+
_In_ PCWSTR lpThreadDescription
66+
)
67+
{
68+
if (m_hModule)
69+
{
70+
if (setThreadDescription == nullptr)
71+
{
72+
setThreadDescription = (PFnSetThreadDescription)GetFunction("SetThreadDescription");
73+
if (setThreadDescription == nullptr)
74+
{
75+
return S_FALSE;
76+
}
77+
}
78+
return setThreadDescription(hThread, lpThreadDescription);
79+
}
80+
81+
return S_FALSE;
82+
}
83+
5584
static NtdllLibrary NtdllLibraryObject;
5685
NtdllLibrary* NtdllLibrary::Instance = &NtdllLibraryObject;
5786

lib/Common/Core/DelayLoadLibrary.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,35 @@ class DelayLoadLibrary
2727

2828
#if _WIN32
2929

30+
// This needs to be delay loaded because SetThreadDescription is available only
31+
// on Win10 1607+
32+
class Kernel32Library : protected DelayLoadLibrary
33+
{
34+
private:
35+
typedef HRESULT (WINAPI *PFnSetThreadDescription)(
36+
_In_ HANDLE hThread,
37+
_In_ PCWSTR lpThreadDescription
38+
);
39+
40+
PFnSetThreadDescription setThreadDescription;
41+
42+
public:
43+
static Kernel32Library* Instance;
44+
45+
Kernel32Library() : DelayLoadLibrary(),
46+
setThreadDescription(NULL)
47+
{
48+
this->EnsureFromSystemDirOnly();
49+
}
50+
51+
LPCTSTR GetLibraryName() const;
52+
53+
HRESULT WINAPI SetThreadDescription(
54+
_In_ HANDLE hThread,
55+
_In_ PCWSTR lpThreadDescription
56+
);
57+
};
58+
3059
// This needs to be delay loaded because it is available on
3160
// Win8 only
3261
class NtdllLibrary : protected DelayLoadLibrary

lib/Common/Memory/Recycler.cpp

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5059,20 +5059,25 @@ Recycler::EnableConcurrent(JsUtil::ThreadService *threadService, bool startAllTh
50595059

50605060
if (startConcurrentThread)
50615061
{
5062-
HANDLE concurrentThread = (HANDLE)PlatformAgnostic::Thread::Create(Recycler::ConcurrentThreadStackSize, &Recycler::StaticThreadProc, this, PlatformAgnostic::Thread::ThreadInitStackSizeParamIsAReservation);
5063-
if (concurrentThread != nullptr)
5062+
auto concurrentThread = PlatformAgnostic::Thread::Create(Recycler::ConcurrentThreadStackSize,
5063+
&Recycler::StaticThreadProc, this,
5064+
PlatformAgnostic::Thread::ThreadInitStackSizeParamIsAReservation,
5065+
_u("Chakra Background Recycler"));
5066+
5067+
if (concurrentThread != PlatformAgnostic::Thread::InvalidHandle)
50645068
{
5069+
HANDLE concurrentThreadWin32Handle = reinterpret_cast<HANDLE>(concurrentThread);
50655070
// Wait for recycler thread to initialize
5066-
HANDLE handle[2] = { this->concurrentWorkDoneEvent, concurrentThread };
5071+
HANDLE handle[2] = { this->concurrentWorkDoneEvent, concurrentThreadWin32Handle };
50675072
DWORD ret = WaitForMultipleObjectsEx(2, handle, FALSE, INFINITE, FALSE);
50685073
if (ret == WAIT_OBJECT_0)
50695074
{
50705075
this->threadService = threadService;
5071-
this->concurrentThread = concurrentThread;
5076+
this->concurrentThread = concurrentThreadWin32Handle;
50725077
return true;
50735078
}
50745079

5075-
CloseHandle(concurrentThread);
5080+
CloseHandle(concurrentThreadWin32Handle);
50765081
}
50775082
}
50785083

@@ -6702,7 +6707,14 @@ RecyclerParallelThread::EnableConcurrent(bool waitForThread)
67026707
return false;
67036708
}
67046709

6705-
this->concurrentThread = (HANDLE)PlatformAgnostic::Thread::Create(Recycler::ConcurrentThreadStackSize, &RecyclerParallelThread::StaticThreadProc, this, PlatformAgnostic::Thread::ThreadInitStackSizeParamIsAReservation);
6710+
auto threadHandle = PlatformAgnostic::Thread::Create(Recycler::ConcurrentThreadStackSize,
6711+
&RecyclerParallelThread::StaticThreadProc, this,
6712+
PlatformAgnostic::Thread::ThreadInitStackSizeParamIsAReservation, _u("Chakra Recycler Parallel Thread"));
6713+
6714+
if (threadHandle != PlatformAgnostic::Thread::InvalidHandle)
6715+
{
6716+
this->concurrentThread = reinterpret_cast<HANDLE>(threadHandle);
6717+
}
67066718

67076719
if (this->concurrentThread != nullptr && waitForThread)
67086720
{

lib/Common/PlatformAgnostic/Thread.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,12 @@ class Thread
1818

1919
typedef uintptr_t ThreadHandle;
2020

21+
static const uintptr_t InvalidHandle = (uintptr_t)-1;
22+
2123
static ThreadHandle Create(unsigned int stack_size,
2224
unsigned int ( *start_address )( void * ),
2325
void* arg_list,
24-
ThreadInitFlag init_flag);
26+
ThreadInitFlag init_flag,
27+
const char16* description);
2528
};
2629
} // namespace PlatformAgnostic

lib/Runtime/PlatformAgnostic/Platform/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ set(PL_SOURCE_FILES
55
Common/HiResTimer.cpp
66
Common/DateTime.cpp
77
Linux/NumbersUtility.cpp
8-
Linux/Thread.cpp
8+
Common/Thread.cpp
99
Common/Trace.cpp
1010
Common/SystemInfo.Common.cpp
1111
)

lib/Runtime/PlatformAgnostic/Platform/Linux/Thread.cpp renamed to lib/Runtime/PlatformAgnostic/Platform/Common/Thread.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@ namespace PlatformAgnostic
1313
Thread::ThreadHandle Thread::Create(unsigned stack_size,
1414
unsigned ( *start_address )( void * ),
1515
void* arg_list,
16-
ThreadInitFlag init_flag)
16+
ThreadInitFlag init_flag,
17+
const char16* /*name*/)
1718
{
1819
unsigned int flag = 0;
1920

lib/Runtime/PlatformAgnostic/Platform/Windows/Thread.cpp

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ namespace PlatformAgnostic
1212
Thread::ThreadHandle Thread::Create(unsigned stack_size,
1313
unsigned ( __stdcall *start_address )( void * ),
1414
void* arg_list,
15-
ThreadInitFlag init_flag)
15+
ThreadInitFlag init_flag,
16+
const char16* description)
1617
{
1718
unsigned int flag = 0;
1819

@@ -31,6 +32,18 @@ namespace PlatformAgnostic
3132
Assert(false);
3233
}
3334

34-
return _beginthreadex(nullptr, stack_size, start_address, arg_list, flag, nullptr);
35+
uintptr_t handle = _beginthreadex(nullptr, stack_size, start_address, arg_list, flag, nullptr);
36+
37+
if (handle == 0)
38+
{
39+
return InvalidHandle;
40+
}
41+
42+
if (description != nullptr)
43+
{
44+
Kernel32Library::Instance->SetThreadDescription((HANDLE) handle, description);
45+
}
46+
47+
return handle;
3548
}
3649
} // namespace PlatformAgnostic

0 commit comments

Comments
 (0)