mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Use QueryThreadCycleTime for mitigation of busy waiting
This commit is contained in:
parent
e7d0fa8f10
commit
b5e3de76cb
@ -24,4 +24,11 @@ namespace Time
|
|||||||
QueryPerformanceCounter(&qpc);
|
QueryPerformanceCounter(&qpc);
|
||||||
return qpc.QuadPart;
|
return qpc.QuadPart;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline ULONG64 queryThreadCycleTime()
|
||||||
|
{
|
||||||
|
ULONG64 cycleTime = 0;
|
||||||
|
QueryThreadCycleTime(GetCurrentThread(), &cycleTime);
|
||||||
|
return cycleTime;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,10 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
typedef unsigned long DWORD;
|
|
||||||
|
|
||||||
namespace Config
|
namespace Config
|
||||||
{
|
{
|
||||||
const int delayedFlipModeTimeout = 200;
|
const unsigned delayedFlipModeTimeout = 200;
|
||||||
const int evictionTimeout = 200;
|
const unsigned evictionTimeout = 200;
|
||||||
const int maxPaletteUpdatesPerMs = 5;
|
const unsigned maxPaletteUpdatesPerMs = 5;
|
||||||
const int maxUserModeDisplayDrivers = 3;
|
const unsigned maxUserModeDisplayDrivers = 3;
|
||||||
|
const unsigned threadSwitchCycleTime = 3 * 1000 * 1000;
|
||||||
}
|
}
|
||||||
|
@ -231,7 +231,6 @@
|
|||||||
<ClInclude Include="Win32\Log.h" />
|
<ClInclude Include="Win32\Log.h" />
|
||||||
<ClInclude Include="Win32\MsgHooks.h" />
|
<ClInclude Include="Win32\MsgHooks.h" />
|
||||||
<ClInclude Include="Win32\Registry.h" />
|
<ClInclude Include="Win32\Registry.h" />
|
||||||
<ClInclude Include="Win32\TimeFunctions.h" />
|
|
||||||
<ClInclude Include="Win32\WaitFunctions.h" />
|
<ClInclude Include="Win32\WaitFunctions.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@ -302,7 +301,6 @@
|
|||||||
<ClCompile Include="Win32\Log.cpp" />
|
<ClCompile Include="Win32\Log.cpp" />
|
||||||
<ClCompile Include="Win32\MsgHooks.cpp" />
|
<ClCompile Include="Win32\MsgHooks.cpp" />
|
||||||
<ClCompile Include="Win32\Registry.cpp" />
|
<ClCompile Include="Win32\Registry.cpp" />
|
||||||
<ClCompile Include="Win32\TimeFunctions.cpp" />
|
|
||||||
<ClCompile Include="Win32\WaitFunctions.cpp" />
|
<ClCompile Include="Win32\WaitFunctions.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||||
|
@ -357,9 +357,6 @@
|
|||||||
<ClInclude Include="Win32\WaitFunctions.h">
|
<ClInclude Include="Win32\WaitFunctions.h">
|
||||||
<Filter>Header Files\Win32</Filter>
|
<Filter>Header Files\Win32</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="Win32\TimeFunctions.h">
|
|
||||||
<Filter>Header Files\Win32</Filter>
|
|
||||||
</ClInclude>
|
|
||||||
<ClInclude Include="Direct3d\Direct3dMaterial.h">
|
<ClInclude Include="Direct3d\Direct3dMaterial.h">
|
||||||
<Filter>Header Files\Direct3d</Filter>
|
<Filter>Header Files\Direct3d</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@ -572,9 +569,6 @@
|
|||||||
<ClCompile Include="Win32\WaitFunctions.cpp">
|
<ClCompile Include="Win32\WaitFunctions.cpp">
|
||||||
<Filter>Source Files\Win32</Filter>
|
<Filter>Source Files\Win32</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Win32\TimeFunctions.cpp">
|
|
||||||
<Filter>Source Files\Win32</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="Direct3d\Direct3dMaterial.cpp">
|
<ClCompile Include="Direct3d\Direct3dMaterial.cpp">
|
||||||
<Filter>Source Files\Direct3d</Filter>
|
<Filter>Source Files\Direct3d</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -20,7 +20,6 @@
|
|||||||
#include <Win32/DisplayMode.h>
|
#include <Win32/DisplayMode.h>
|
||||||
#include <Win32/MsgHooks.h>
|
#include <Win32/MsgHooks.h>
|
||||||
#include <Win32/Registry.h>
|
#include <Win32/Registry.h>
|
||||||
#include <Win32/TimeFunctions.h>
|
|
||||||
#include <Win32/WaitFunctions.h>
|
#include <Win32/WaitFunctions.h>
|
||||||
|
|
||||||
HRESULT WINAPI SetAppCompatData(DWORD, DWORD);
|
HRESULT WINAPI SetAppCompatData(DWORD, DWORD);
|
||||||
@ -106,7 +105,6 @@ namespace
|
|||||||
Compat::Log() << "Installing Direct3D driver hooks";
|
Compat::Log() << "Installing Direct3D driver hooks";
|
||||||
D3dDdi::installHooks(g_origDDrawModule);
|
D3dDdi::installHooks(g_origDDrawModule);
|
||||||
Compat::Log() << "Installing Win32 hooks";
|
Compat::Log() << "Installing Win32 hooks";
|
||||||
Win32::TimeFunctions::installHooks();
|
|
||||||
Win32::WaitFunctions::installHooks();
|
Win32::WaitFunctions::installHooks();
|
||||||
Gdi::VirtualScreen::init();
|
Gdi::VirtualScreen::init();
|
||||||
|
|
||||||
|
@ -1,37 +0,0 @@
|
|||||||
#include <Windows.h>
|
|
||||||
#include <timeapi.h>
|
|
||||||
|
|
||||||
#include <Common/Hook.h>
|
|
||||||
#include <Win32/TimeFunctions.h>
|
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
typedef DWORD(WINAPI* TimeFunc)();
|
|
||||||
|
|
||||||
template <TimeFunc timeFunc>
|
|
||||||
DWORD WINAPI getTime()
|
|
||||||
{
|
|
||||||
thread_local DWORD prevTime = 0;
|
|
||||||
auto origTimeFunc = Compat::getOrigFuncPtr<TimeFunc, timeFunc>();
|
|
||||||
DWORD time = origTimeFunc();
|
|
||||||
if (prevTime == time)
|
|
||||||
{
|
|
||||||
SwitchToThread();
|
|
||||||
time = origTimeFunc();
|
|
||||||
}
|
|
||||||
prevTime = time;
|
|
||||||
return time;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace Win32
|
|
||||||
{
|
|
||||||
namespace TimeFunctions
|
|
||||||
{
|
|
||||||
void installHooks()
|
|
||||||
{
|
|
||||||
HOOK_FUNCTION(kernel32, GetTickCount, getTime<&GetTickCount>);
|
|
||||||
HOOK_FUNCTION(winmm, timeGetTime, getTime<&timeGetTime>);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
namespace Win32
|
|
||||||
{
|
|
||||||
namespace TimeFunctions
|
|
||||||
{
|
|
||||||
void installHooks();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,66 +1,52 @@
|
|||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
#include <timeapi.h>
|
||||||
|
|
||||||
#include <Config/Config.h>
|
|
||||||
#include <Common/Hook.h>
|
#include <Common/Hook.h>
|
||||||
|
#include <Common/Time.h>
|
||||||
|
#include <Config/Config.h>
|
||||||
#include <Win32/WaitFunctions.h>
|
#include <Win32/WaitFunctions.h>
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
DWORD mitigateBusyWaiting(DWORD dwMilliseconds, DWORD waitResult)
|
void mitigateBusyWaiting()
|
||||||
{
|
{
|
||||||
if (0 == dwMilliseconds && WAIT_TIMEOUT == waitResult)
|
thread_local ULONG64 ctLastThreadSwitch = Time::queryThreadCycleTime();
|
||||||
|
ULONG64 ctNow = Time::queryThreadCycleTime();
|
||||||
|
if (ctNow - ctLastThreadSwitch >= Config::threadSwitchCycleTime)
|
||||||
{
|
{
|
||||||
SwitchToThread();
|
Sleep(0);
|
||||||
|
ctLastThreadSwitch = ctNow;
|
||||||
}
|
}
|
||||||
return waitResult;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
DWORD WINAPI msgWaitForMultipleObjects(
|
template <typename FuncPtr, FuncPtr func, typename Result, typename... Params>
|
||||||
DWORD nCount, const HANDLE* pHandles, BOOL fWaitAll, DWORD dwMilliseconds, DWORD dwWakeMask)
|
Result WINAPI mitigatedBusyWaitingFunc(Params... params)
|
||||||
{
|
{
|
||||||
return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(MsgWaitForMultipleObjects)(
|
mitigateBusyWaiting();
|
||||||
nCount, pHandles, fWaitAll, dwMilliseconds, dwWakeMask));
|
return Compat::getOrigFuncPtr<FuncPtr, func>()(params...);
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI msgWaitForMultipleObjectsEx(
|
|
||||||
DWORD nCount, const HANDLE* pHandles, DWORD dwMilliseconds, DWORD dwWakeMask, DWORD dwFlags)
|
|
||||||
{
|
|
||||||
return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(MsgWaitForMultipleObjectsEx)(
|
|
||||||
nCount, pHandles, dwMilliseconds, dwWakeMask, dwFlags));
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI signalObjectAndWait(
|
|
||||||
HANDLE hObjectToSignal, HANDLE hObjectToWaitOn, DWORD dwMilliseconds, BOOL bAlertable)
|
|
||||||
{
|
|
||||||
return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(SignalObjectAndWait)(
|
|
||||||
hObjectToSignal, hObjectToWaitOn, dwMilliseconds, bAlertable));
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI waitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertable)
|
|
||||||
{
|
|
||||||
return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(WaitForSingleObjectEx)(
|
|
||||||
hHandle, dwMilliseconds, bAlertable));
|
|
||||||
}
|
|
||||||
|
|
||||||
DWORD WINAPI waitForMultipleObjectsEx(
|
|
||||||
DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
|
|
||||||
{
|
|
||||||
return mitigateBusyWaiting(dwMilliseconds, CALL_ORIG_FUNC(WaitForMultipleObjectsEx)(
|
|
||||||
nCount, lpHandles, bWaitAll, dwMilliseconds, bAlertable));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define MITIGATE_BUSY_WAITING(module, func) \
|
||||||
|
Compat::hookFunction<decltype(&func), &func>(#module, #func, &mitigatedBusyWaitingFunc<decltype(&func), func>)
|
||||||
|
|
||||||
namespace Win32
|
namespace Win32
|
||||||
{
|
{
|
||||||
namespace WaitFunctions
|
namespace WaitFunctions
|
||||||
{
|
{
|
||||||
void installHooks()
|
void installHooks()
|
||||||
{
|
{
|
||||||
HOOK_FUNCTION(user32, MsgWaitForMultipleObjects, msgWaitForMultipleObjects);
|
MITIGATE_BUSY_WAITING(user32, GetMessageA);
|
||||||
HOOK_FUNCTION(user32, MsgWaitForMultipleObjectsEx, msgWaitForMultipleObjectsEx);
|
MITIGATE_BUSY_WAITING(user32, GetMessageW);
|
||||||
HOOK_FUNCTION(kernel32, SignalObjectAndWait, signalObjectAndWait);
|
MITIGATE_BUSY_WAITING(kernel32, GetTickCount);
|
||||||
HOOK_FUNCTION(kernel32, WaitForSingleObjectEx, waitForSingleObjectEx);
|
MITIGATE_BUSY_WAITING(user32, MsgWaitForMultipleObjects);
|
||||||
HOOK_FUNCTION(kernel32, WaitForMultipleObjectsEx, waitForMultipleObjectsEx);
|
MITIGATE_BUSY_WAITING(user32, MsgWaitForMultipleObjectsEx);
|
||||||
|
MITIGATE_BUSY_WAITING(user32, PeekMessageA);
|
||||||
|
MITIGATE_BUSY_WAITING(user32, PeekMessageW);
|
||||||
|
MITIGATE_BUSY_WAITING(kernel32, SignalObjectAndWait);
|
||||||
|
MITIGATE_BUSY_WAITING(winmm, timeGetTime);
|
||||||
|
MITIGATE_BUSY_WAITING(kernel32, WaitForSingleObjectEx);
|
||||||
|
MITIGATE_BUSY_WAITING(kernel32, WaitForMultipleObjectsEx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user