mirror of
https://github.com/narzoul/DDrawCompat
synced 2024-12-30 08:55:36 +01:00
Added CpuAffinity setting
This commit is contained in:
parent
b3b54d5fbd
commit
74460b2d24
@ -2,5 +2,6 @@
|
||||
|
||||
namespace Config
|
||||
{
|
||||
Settings::CpuAffinity cpuAffinity;
|
||||
Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
#include <Config/Settings/ThreadPriorityBoost.h>
|
||||
|
||||
namespace Config
|
||||
@ -8,5 +9,6 @@ namespace Config
|
||||
const unsigned evictionTimeout = 200;
|
||||
const unsigned maxPaletteUpdatesPerMs = 5;
|
||||
|
||||
extern Settings::CpuAffinity cpuAffinity;
|
||||
extern Settings::ThreadPriorityBoost threadPriorityBoost;
|
||||
}
|
||||
|
36
DDrawCompat/Config/ListSetting.cpp
Normal file
36
DDrawCompat/Config/ListSetting.cpp
Normal file
@ -0,0 +1,36 @@
|
||||
#include <Config/ListSetting.h>
|
||||
#include <Config/Parser.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
ListSetting::ListSetting(const std::string& name, const std::string& default)
|
||||
: Setting(name)
|
||||
, m_default(default)
|
||||
{
|
||||
}
|
||||
|
||||
void ListSetting::resetValue()
|
||||
{
|
||||
setValue(m_default);
|
||||
}
|
||||
|
||||
void ListSetting::setValue(const std::string& value)
|
||||
{
|
||||
std::vector<std::string> values;
|
||||
std::size_t startPos = 0;
|
||||
std::size_t endPos = 0;
|
||||
|
||||
do
|
||||
{
|
||||
endPos = value.find(',', startPos);
|
||||
if (endPos == std::string::npos)
|
||||
{
|
||||
endPos = value.length();
|
||||
}
|
||||
values.push_back(Parser::trim(value.substr(startPos, endPos - startPos)));
|
||||
startPos = endPos + 1;
|
||||
} while (endPos < value.length());
|
||||
|
||||
setValues(values);
|
||||
}
|
||||
}
|
21
DDrawCompat/Config/ListSetting.h
Normal file
21
DDrawCompat/Config/ListSetting.h
Normal file
@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <Config/Setting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
class ListSetting : public Setting
|
||||
{
|
||||
protected:
|
||||
ListSetting(const std::string& name, const std::string& default);
|
||||
|
||||
private:
|
||||
void resetValue() override;
|
||||
void setValue(const std::string& value) override;
|
||||
virtual void setValues(const std::vector<std::string>& values) = 0;
|
||||
|
||||
std::string m_default;
|
||||
};
|
||||
}
|
@ -11,7 +11,6 @@ namespace
|
||||
{
|
||||
void setConfig(const std::string& name, const std::string& value, const std::string& source);
|
||||
std::string tolower(const std::string& str);
|
||||
std::string trim(const std::string& str);
|
||||
|
||||
auto& getSettings()
|
||||
{
|
||||
@ -52,7 +51,7 @@ namespace
|
||||
throw Config::ParsingError("missing '=' separator");
|
||||
}
|
||||
|
||||
setConfig(trim(line.substr(0, pos)), trim(line.substr(pos + 1)), source);
|
||||
setConfig(Config::Parser::trim(line.substr(0, pos)), Config::Parser::trim(line.substr(pos + 1)), source);
|
||||
}
|
||||
catch (const Config::ParsingError& error)
|
||||
{
|
||||
@ -94,23 +93,6 @@ namespace
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str)
|
||||
{
|
||||
auto result(str);
|
||||
auto pos = str.find_last_not_of(" \t");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result.resize(pos + 1);
|
||||
}
|
||||
|
||||
pos = result.find_first_not_of(" \t");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result = result.substr(pos);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
namespace Config
|
||||
@ -160,10 +142,36 @@ namespace Config
|
||||
}
|
||||
}
|
||||
|
||||
unsigned parseUnsigned(const std::string& value)
|
||||
{
|
||||
if (value.empty() || std::string::npos != value.find_first_not_of("0123456789"))
|
||||
{
|
||||
throw ParsingError("not an unsigned integer: '" + value + "'");
|
||||
}
|
||||
return std::strtoul(value.c_str(), nullptr, 10);
|
||||
}
|
||||
|
||||
void registerSetting(Setting& setting)
|
||||
{
|
||||
const auto& name = setting.getName();
|
||||
getSettings().emplace(name, setting);
|
||||
}
|
||||
|
||||
std::string trim(const std::string& str)
|
||||
{
|
||||
auto result(str);
|
||||
auto pos = str.find_last_not_of(" \t");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result.resize(pos + 1);
|
||||
}
|
||||
|
||||
pos = result.find_first_not_of(" \t");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
result = result.substr(pos);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <filesystem>
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
@ -16,6 +17,8 @@ namespace Config
|
||||
namespace Parser
|
||||
{
|
||||
void loadAllConfigFiles(const std::filesystem::path& processPath);
|
||||
unsigned parseUnsigned(const std::string& value);
|
||||
void registerSetting(Setting& setting);
|
||||
std::string trim(const std::string& str);
|
||||
}
|
||||
}
|
||||
|
73
DDrawCompat/Config/Settings/CpuAffinity.cpp
Normal file
73
DDrawCompat/Config/Settings/CpuAffinity.cpp
Normal file
@ -0,0 +1,73 @@
|
||||
#include <Config/Parser.h>
|
||||
#include <Config/Settings/CpuAffinity.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
CpuAffinity::CpuAffinity()
|
||||
: ListSetting("CpuAffinity", "1")
|
||||
, m_value(1)
|
||||
{
|
||||
}
|
||||
|
||||
std::string CpuAffinity::getValueStr() const
|
||||
{
|
||||
if (0 == m_value)
|
||||
{
|
||||
return "app";
|
||||
}
|
||||
|
||||
if (UINT_MAX == m_value)
|
||||
{
|
||||
return "all";
|
||||
}
|
||||
|
||||
std::string result;
|
||||
for (unsigned i = 0; i < 32; ++i)
|
||||
{
|
||||
if (m_value & (1U << i))
|
||||
{
|
||||
result += ',' + std::to_string(i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
return result.substr(1);
|
||||
}
|
||||
|
||||
void CpuAffinity::setValues(const std::vector<std::string>& values)
|
||||
{
|
||||
if (values.empty())
|
||||
{
|
||||
throw ParsingError("empty list is not allowed");
|
||||
}
|
||||
|
||||
if (1 == values.size())
|
||||
{
|
||||
if ("app" == values.front())
|
||||
{
|
||||
m_value = 0;
|
||||
return;
|
||||
}
|
||||
else if ("all" == values.front())
|
||||
{
|
||||
m_value = UINT_MAX;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned result = 0;
|
||||
for (const auto& value : values)
|
||||
{
|
||||
auto num = Parser::parseUnsigned(value);
|
||||
if (num < 1 || num > 32)
|
||||
{
|
||||
throw ParsingError("'" + value + "' is not an integer between 1 and 32");
|
||||
}
|
||||
result |= 1U << (num - 1);
|
||||
}
|
||||
|
||||
m_value = result;
|
||||
}
|
||||
}
|
||||
}
|
23
DDrawCompat/Config/Settings/CpuAffinity.h
Normal file
23
DDrawCompat/Config/Settings/CpuAffinity.h
Normal file
@ -0,0 +1,23 @@
|
||||
#pragma once
|
||||
|
||||
#include <Config/ListSetting.h>
|
||||
|
||||
namespace Config
|
||||
{
|
||||
namespace Settings
|
||||
{
|
||||
class CpuAffinity : public ListSetting
|
||||
{
|
||||
public:
|
||||
CpuAffinity();
|
||||
|
||||
unsigned get() const { return m_value; }
|
||||
|
||||
private:
|
||||
std::string getValueStr() const override;
|
||||
void setValues(const std::vector<std::string>& values) override;
|
||||
|
||||
unsigned m_value;
|
||||
};
|
||||
}
|
||||
}
|
@ -179,8 +179,10 @@
|
||||
<ClInclude Include="Common\Time.h" />
|
||||
<ClInclude Include="Config\Config.h" />
|
||||
<ClInclude Include="Config\EnumSetting.h" />
|
||||
<ClInclude Include="Config\ListSetting.h" />
|
||||
<ClInclude Include="Config\Parser.h" />
|
||||
<ClInclude Include="Config\Setting.h" />
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h" />
|
||||
<ClInclude Include="Config\Settings\ThreadPriorityBoost.h" />
|
||||
<ClInclude Include="D3dDdi\Adapter.h" />
|
||||
<ClInclude Include="D3dDdi\AdapterCallbacks.h" />
|
||||
@ -277,8 +279,10 @@
|
||||
<ClCompile Include="Common\Time.cpp" />
|
||||
<ClCompile Include="Config\Config.cpp" />
|
||||
<ClCompile Include="Config\EnumSetting.cpp" />
|
||||
<ClCompile Include="Config\ListSetting.cpp" />
|
||||
<ClCompile Include="Config\Parser.cpp" />
|
||||
<ClCompile Include="Config\Setting.cpp" />
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp" />
|
||||
<ClCompile Include="D3dDdi\Adapter.cpp" />
|
||||
<ClCompile Include="D3dDdi\AdapterCallbacks.cpp" />
|
||||
<ClCompile Include="D3dDdi\AdapterFuncs.cpp" />
|
||||
|
@ -85,6 +85,9 @@
|
||||
<Filter Include="Header Files\Config\Settings">
|
||||
<UniqueIdentifier>{bdde0d15-27ab-43a7-9c0a-294df6a52bad}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Source Files\Config\Settings">
|
||||
<UniqueIdentifier>{0b4eec6c-ece5-4417-913c-8829b34ec08c}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="Gdi\Gdi.h">
|
||||
@ -408,6 +411,12 @@
|
||||
<ClInclude Include="Win32\Thread.h">
|
||||
<Filter>Header Files\Win32</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\ListSetting.h">
|
||||
<Filter>Header Files\Config</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="Config\Settings\CpuAffinity.h">
|
||||
<Filter>Header Files\Config\Settings</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="Gdi\Gdi.cpp">
|
||||
@ -638,9 +647,15 @@
|
||||
<ClCompile Include="Config\EnumSetting.cpp">
|
||||
<Filter>Source Files\Config</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\ListSetting.cpp">
|
||||
<Filter>Source Files\Config</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Win32\Thread.cpp">
|
||||
<Filter>Source Files\Win32</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="Config\Settings\CpuAffinity.cpp">
|
||||
<Filter>Source Files\Config\Settings</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ResourceCompile Include="DDrawCompat.rc">
|
||||
|
@ -212,7 +212,6 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
Win32::Thread::installHooks();
|
||||
Compat::closeDbgEng();
|
||||
|
||||
SetProcessAffinityMask(GetCurrentProcess(), 1);
|
||||
timeBeginPeriod(1);
|
||||
setDpiAwareness();
|
||||
SetThemeAppProperties(0);
|
||||
|
@ -7,6 +7,16 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
BOOL WINAPI setProcessAffinityMask(HANDLE hProcess, DWORD_PTR dwProcessAffinityMask)
|
||||
{
|
||||
LOG_FUNC("SetProcessAffinityMask", hProcess, Compat::hex(dwProcessAffinityMask));
|
||||
if (0 != Config::cpuAffinity.get())
|
||||
{
|
||||
return LOG_RESULT(TRUE);
|
||||
}
|
||||
return LOG_RESULT(CALL_ORIG_FUNC(SetProcessAffinityMask)(hProcess, dwProcessAffinityMask));
|
||||
}
|
||||
|
||||
BOOL WINAPI setProcessPriorityBoost(HANDLE hProcess, BOOL bDisablePriorityBoost)
|
||||
{
|
||||
LOG_FUNC("SetProcessPriorityBoost", hProcess, bDisablePriorityBoost);
|
||||
@ -34,6 +44,22 @@ namespace Win32
|
||||
{
|
||||
void applyConfig()
|
||||
{
|
||||
auto cpuAffinity = Config::cpuAffinity.get();
|
||||
if (0 != cpuAffinity)
|
||||
{
|
||||
SYSTEM_INFO si = {};
|
||||
GetSystemInfo(&si);
|
||||
const unsigned cpuCount = min(si.dwNumberOfProcessors, 32);
|
||||
cpuAffinity &= UINT_MAX >> (32 - cpuCount);
|
||||
|
||||
if (0 == cpuAffinity || !CALL_ORIG_FUNC(SetProcessAffinityMask)(GetCurrentProcess(), cpuAffinity))
|
||||
{
|
||||
Compat::Log() << (0 == cpuAffinity ? "Invalid" : "Failed to set") << " CPU affinity, falling back to default";
|
||||
Config::cpuAffinity.reset();
|
||||
CALL_ORIG_FUNC(SetProcessAffinityMask)(GetCurrentProcess(), Config::cpuAffinity.get());
|
||||
}
|
||||
}
|
||||
|
||||
switch (Config::threadPriorityBoost.get())
|
||||
{
|
||||
case Config::Settings::ThreadPriorityBoost::OFF:
|
||||
@ -53,6 +79,7 @@ namespace Win32
|
||||
|
||||
void installHooks()
|
||||
{
|
||||
HOOK_FUNCTION(kernel32, SetProcessAffinityMask, setProcessAffinityMask);
|
||||
HOOK_FUNCTION(kernel32, SetProcessPriorityBoost, setProcessPriorityBoost);
|
||||
HOOK_FUNCTION(kernel32, SetThreadPriorityBoost, setThreadPriorityBoost);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user