Tier0: add new thread tools

- Add ThreadInMainOrServerFrameThread()
- Add ThreadCouldDoServerWork()
- Add ThreadJoinServerJob()
- Properly implement ThreadInServerFrameThread()
- Export all these functions for external DLL usage (plugins, etc)
This commit is contained in:
Kawe Mazidjatari 2024-04-01 00:46:21 +02:00
parent 77c0f5031b
commit 32828e4e52
2 changed files with 57 additions and 14 deletions

View File

@ -1,6 +1,9 @@
#ifndef THREADTOOLS_H
#define THREADTOOLS_H
#include "dbg.h"
#ifndef BUILDING_MATHLIB
#include "jobthread.h"
#endif // BUILDING_MATHLIB
inline void ThreadSleep(unsigned nMilliseconds)
{
@ -116,16 +119,14 @@ FORCEINLINE ThreadId_t ThreadGetCurrentId()
extern ThreadId_t* g_ThreadMainThreadID;
extern ThreadId_t* g_ThreadServerFrameThreadID;
inline JobID_t* g_CurrentServerFrameJobID;
inline JobID_t* g_AllocatedServerFrameJobID;
FORCEINLINE bool ThreadInMainThread()
{
return (ThreadGetCurrentId() == (*g_ThreadMainThreadID));
}
FORCEINLINE bool ThreadInServerFrameThread()
{
return (ThreadGetCurrentId() == (*g_ThreadServerFrameThreadID));
}
PLATFORM_INTERFACE bool ThreadInMainThread();
PLATFORM_INTERFACE bool ThreadInServerFrameThread();
PLATFORM_INTERFACE bool ThreadInMainOrServerFrameThread();
PLATFORM_INTERFACE bool ThreadCouldDoServerWork();
PLATFORM_INTERFACE void ThreadJoinServerJob();
#endif // !BUILDING_MATHLIB
@ -263,7 +264,7 @@ typedef CInterlockedIntT<unsigned> CInterlockedUInt;
#ifndef BUILDING_MATHLIB
//=============================================================================
inline ThreadId_t(*v_DeclareCurrentThreadIsMainThread)(void);
#endif // !BUILDING_MATHLIB
@ -562,15 +563,20 @@ class VThreadTools : public IDetour
{
virtual void GetAdr(void) const
{
LogFunAdr("DeclareCurrentThreadIsMainThread", v_DeclareCurrentThreadIsMainThread);
LogVarAdr("g_ThreadMainThreadID", g_ThreadMainThreadID);
LogVarAdr("g_ThreadServerFrameThreadID", g_ThreadServerFrameThreadID);
LogVarAdr("g_CurrentServerFrameJobID", g_CurrentServerFrameJobID);
LogVarAdr("g_AllocatedServerFrameJobID", g_AllocatedServerFrameJobID);
}
virtual void GetFun(void) const
virtual void GetFun(void) const { }
virtual void GetVar(void) const
{
g_GameDll.FindPatternSIMD("48 83 EC 28 FF 15 ?? ?? ?? ?? 89 05 ?? ?? ?? ?? 48 83 C4 28").GetPtr(v_DeclareCurrentThreadIsMainThread);
g_GameDll.FindPatternSIMD("66 89 54 24 ?? 53 55 56 57 41 54 48 81 EC ?? ?? ?? ??")
.FindPatternSelf("39 05").ResolveRelativeAddressSelf(2, 6).GetPtr(g_CurrentServerFrameJobID);
g_GameDll.FindPatternSIMD("48 83 EC 28 FF 15 ?? ?? ?? ?? 8B 0D ?? ?? ?? ??")
.FindPatternSelf("8B 0D").ResolveRelativeAddressSelf(2, 6).GetPtr(g_AllocatedServerFrameJobID);
}
virtual void GetVar(void) const { }
virtual void GetCon(void) const { }
virtual void Detour(const bool /*bAttach*/) const { }
};

View File

@ -7,6 +7,7 @@
//===========================================================================//
#include "tier0/threadtools.h"
#include "tier0/jobthread.h"
#define INIT_SEM_COUNT 0
#define MAX_SEM_COUNT 1
@ -198,6 +199,42 @@ void CThreadSpinRWLock::SpinLockForRead()
}
}
bool ThreadInMainThread()
{
return (ThreadGetCurrentId() == (*g_ThreadMainThreadID));
}
bool ThreadInServerFrameThread()
{
return (ThreadGetCurrentId() == (*g_ThreadServerFrameThreadID)
&& JT_GetCurrentJob() == (*g_CurrentServerFrameJobID));
}
bool ThreadInMainOrServerFrameThread()
{
return (ThreadInMainThread() || ThreadInServerFrameThread());
}
bool ThreadCouldDoServerWork()
{
if (*g_ThreadServerFrameThreadID == -1)
return ThreadInMainThread();
return ThreadInServerFrameThread();
}
void ThreadJoinServerJob()
{
if (ThreadCouldDoServerWork())
return; // No job to join
if (*g_AllocatedServerFrameJobID)
{
JT_WaitForJobAndOnlyHelpWithJobTypes(*g_AllocatedServerFrameJobID, NULL, 0xFFFFFFFFFFFFFFFF);
*g_AllocatedServerFrameJobID = 0;
}
}
// NOTE: originally the game exported 'ThreadInMainThread()' and ThreadInServerFrameThread(),
// but since the game is built static, and all instances of said functions are inline, we had
// to export the variable symbols instead and get them here to reimplement said functions.