Skip to content

Commit

Permalink
Set custom names for all of our threads
Browse files Browse the repository at this point in the history
This is helpful when debugging, especially with all of the IO worker
threads created by the asio-based socket code.
  • Loading branch information
dgelessus committed Nov 5, 2023
1 parent 1c4209c commit edffd7f
Show file tree
Hide file tree
Showing 14 changed files with 57 additions and 1 deletion.
2 changes: 2 additions & 0 deletions Sources/Plasma/Apps/plClient/plClientLoader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ You can contact Cyan Worlds, Inc. by email [email protected]

void plClientLoader::Run()
{
SetThisThreadName(ST_LITERAL("plClientLoader"));

plResManager *resMgr = new plResManager;
resMgr->SetDataPath("dat");
hsgResMgr::Init(resMgr);
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/Apps/plClient/win32/winmain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ INT_PTR CALLBACK UruLoginDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPA
{
s_loginDlgRunning = true;
s_statusThread = std::thread([hwndDlg]() {
hsThread::SetThisThreadName(ST_LITERAL("LoginDialogShardStatus"));
#ifdef USE_VLD
VLDEnable();
#endif
Expand Down
4 changes: 4 additions & 0 deletions Sources/Plasma/Apps/plUruLauncher/plClientLauncher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ static size_t ICurlCallback(void* buffer, size_t size, size_t nmemb, void* threa

void plShardStatus::Run()
{
SetThisThreadName(ST_LITERAL("plShardStatus"));

ST::string url = GetServerStatusUrl();

// initialize CURL
Expand Down Expand Up @@ -180,6 +182,8 @@ class plRedistUpdater : public hsThread

void Run() override
{
SetThisThreadName(ST_LITERAL("plRedistUpdater"));

while (!fRedistQueue.empty()) {
if (fInstallProc(fRedistQueue.back()))
fRedistQueue.pop_back();
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/CoreLib/hsThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ void hsThread::Start()
{
if (!fThread.joinable()) {
fThread = std::thread([this]() {
hsThread::SetThisThreadName(ST_LITERAL("hsNoNameThread"));
#ifdef USE_VLD
// Needs to be enabled for each thread except the WinMain
VLDEnable();
Expand Down
5 changes: 5 additions & 0 deletions Sources/Plasma/CoreLib/hsThread.h
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,11 @@ class hsThread
// WILL NOT stop a detached thread!
void StartDetached();

// Set a name for the current thread, to be displayed in debuggers and such.
// If possible, don't use names longer than 15 characters,
// because Linux has a really low limit.
static void SetThisThreadName(const ST::string& name);

static inline size_t ThisThreadHash()
{
return std::hash<std::thread::id>()(std::this_thread::get_id());
Expand Down
17 changes: 17 additions & 0 deletions Sources/Plasma/CoreLib/hsThread_Unix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,23 @@ int clock_gettime(int clocktype, struct timespec* ts)

/////////////////////////////////////////////////////////////////////////////

void hsThread::SetThisThreadName(const ST::string& name)
{
#if defined(HS_BUILD_FOR_APPLE)
// The Apple version doesn't take a thread argument and always operates on the current thread.
int res = pthread_setname_np(name.c_str());
hsAssert(res == 0, "Failed to set thread name");
#elif defined(HS_BUILD_FOR_LINUX)
// On Linux, thread names must fit into 16 bytes, including the terminator.
char buf[16];
strncpy(buf, name.c_str(), sizeof(buf));
buf[sizeof(buf) - 1] = '\0';
int res = pthread_setname_np(pthread_self(), buf);
hsAssert(res == 0, "Failed to set thread name");
#endif
// Because this is just a debugging help, do nothing by default (sorry, BSDs).
}

hsGlobalSemaphore::hsGlobalSemaphore(int initialValue, const ST::string& name)
{
#ifdef USE_SEMA
Expand Down
15 changes: 15 additions & 0 deletions Sources/Plasma/CoreLib/hsThread_Win.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,21 @@ You can contact Cyan Worlds, Inc. by email [email protected]
#include "hsThread.h"
#include "hsExceptions.h"

void hsThread::SetThisThreadName(const ST::string& name)
{
// SetThreadDescription is only supported since Windows 10 v1607.
// There's an alternative solution that also works on older versions,
// but it's specific to Visual Studio and the "interface" is really gnarly.
// Because this is just a debugging help, that probably isn't worth the effort.
// https://learn.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code?view=vs-2022#set-a-thread-name-by-throwing-an-exception
static plOptionalWinCall<HRESULT(HANDLE, PCWSTR)> SetThreadDescription(L"KernelBase", "SetThreadDescription");

auto result = SetThreadDescription(GetCurrentThread(), name.to_wchar().c_str());
if (result) {
hsAssert(SUCCEEDED(*result), ST::format("Failed to set thread name: {}", hsCOMError(*result)).c_str());
}
}

hsGlobalSemaphore::hsGlobalSemaphore(int initialValue, const ST::string& name)
{
fSemaH = ::CreateSemaphoreW(nullptr, initialValue, std::numeric_limits<LONG>::max(), name.to_wchar().data());
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/FeatureLib/pfPatcher/pfPatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,7 @@ bool pfPatcherWorker::IssueRequest()

void pfPatcherWorker::Run()
{
SetThisThreadName(ST_LITERAL("pfPatcherWorker"));
// So here's the rub:
// We have one or many manifests in the fRequests deque. We begin issuing those requests one-by one, starting here.
// As we receive the answer, the NetCli thread populates fQueuedFiles and pings the fFileSignal semaphore, then issues the next request...
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceDns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ struct DnsResolver
{
// Start the resolver thread
fLookupThread = AsyncThreadCreate([this] {
hsThread::SetThisThreadName(ST_LITERAL("AceDnsResolver"));
fContext.run();
});
}
Expand Down
5 changes: 4 additions & 1 deletion Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceSocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,14 @@ struct AsyncIoPool
}

// create IO worker threads
size_t i = 0;
for (auto& threadHandle : fThreadHandles) {
threadHandle = AsyncThreadCreate([this] {
threadHandle = AsyncThreadCreate([this, i] {
hsThread::SetThisThreadName(ST::format("AceSocketPool{02d}", i));
// This can be run concurrently from several threads
fContext.run();
});
i++;
}
}

Expand Down
2 changes: 2 additions & 0 deletions Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceThread.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ You can contact Cyan Worlds, Inc. by email [email protected]

static void CreateThreadProc(AsyncThreadRef thread)
{
hsThread::SetThisThreadName(ST_LITERAL("NoNameAceThread"));

#ifdef USE_VLD
VLDEnable();
#endif
Expand Down
1 change: 1 addition & 0 deletions Sources/Plasma/NucleusLib/pnAsyncCoreExe/pnAceTimer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ struct AsyncTimerManager
AsyncTimerManager() : fWorkGuard(fContext.get_executor())
{
fTimerThread = AsyncThreadCreate([this] {
hsThread::SetThisThreadName(ST_LITERAL("AceTimerMgr"));
fContext.run();
});
}
Expand Down
2 changes: 2 additions & 0 deletions Sources/Plasma/PubUtilLib/plAudioCore/plSoundBuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,8 @@ static plAudioFileReader *CreateReader( bool fullpath, const plFileName &filenam

void plSoundPreloader::Run()
{
SetThisThreadName(ST_LITERAL("SoundPreloader"));

std::vector<plSoundBuffer*> templist;

while (fRunning)
Expand Down
1 change: 1 addition & 0 deletions Sources/Tools/MaxComponent/plPickMaterialMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ class hsHackWinFindThread : public hsThread
public:
void Run() override
{
SetThisThreadName(ST_LITERAL("hsHackWinFindThread"));
while (1)
{
HWND hMtlDlg = FindWindow(nullptr, _T("Material/Map Browser"));
Expand Down

0 comments on commit edffd7f

Please sign in to comment.