diff --git a/src/common/Threading/ProcessPriority.cpp b/src/common/Threading/ProcessPriority.cpp new file mode 100644 index 000000000..bc6c48044 --- /dev/null +++ b/src/common/Threading/ProcessPriority.cpp @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * Copyright (C) 2021+ WarheadCore + */ + +#include "ProcessPriority.h" +#include "Log.h" + +#ifdef _WIN32 // Windows +#include +#elif defined(__linux__) +#include +#include +#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 +#endif + +void SetProcessPriority(std::string const& logChannel, uint32 affinity, bool highPriority) +{ + ///- Handle affinity for multiple processors and process priority +#ifdef _WIN32 // Windows + + HANDLE hProcess = GetCurrentProcess(); + if (affinity > 0) + { + ULONG_PTR appAff; + ULONG_PTR sysAff; + + if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) + { + // remove non accessible processors + ULONG_PTR currentAffinity = affinity & appAff; + + if (!currentAffinity) + LOG_ERROR(logChannel, "Processors marked in UseProcessors bitmask (hex) %x are not accessible. Accessible processors bitmask (hex): %x", affinity, appAff); + else if (SetProcessAffinityMask(hProcess, currentAffinity)) + LOG_INFO(logChannel, "Using processors (bitmask, hex): %x", currentAffinity); + else + LOG_ERROR(logChannel, "Can't set used processors (hex): %x", currentAffinity); + } + } + + if (highPriority) + { + if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) + LOG_INFO(logChannel, "Process priority class set to HIGH"); + else + LOG_ERROR(logChannel, "Can't set process priority class."); + } + +#elif defined(__linux__) // Linux + + if (affinity > 0) + { + cpu_set_t mask; + CPU_ZERO(&mask); + + for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) + if (affinity & (1 << i)) + CPU_SET(i, &mask); + + if (sched_setaffinity(0, sizeof(mask), &mask)) + LOG_ERROR(logChannel, "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); + else + { + CPU_ZERO(&mask); + sched_getaffinity(0, sizeof(mask), &mask); + LOG_INFO(logChannel, "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); + } + } + + if (highPriority) + { + if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) + LOG_ERROR(logChannel, "Can't set process priority class, error: %s", strerror(errno)); + else + LOG_INFO(logChannel, "Process priority class set to %i", getpriority(PRIO_PROCESS, 0)); + } + +#else + // Suppresses unused argument warning for all other platforms + (void)logChannel; + (void)affinity; + (void)highPriority; +#endif +} diff --git a/src/common/Threading/ProcessPriority.h b/src/common/Threading/ProcessPriority.h new file mode 100644 index 000000000..0eb162131 --- /dev/null +++ b/src/common/Threading/ProcessPriority.h @@ -0,0 +1,17 @@ +/* + * Copyright (C) 2016+ AzerothCore , released under GNU AGPL v3 license: https://github.com/azerothcore/azerothcore-wotlk/blob/master/LICENSE-AGPL3 + * Copyright (C) 2021+ WarheadCore + */ + +#ifndef _PROCESSPRIO_H +#define _PROCESSPRIO_H + +#include "Define.h" +#include + +#define CONFIG_PROCESSOR_AFFINITY "UseProcessors" +#define CONFIG_HIGH_PRIORITY "ProcessPriority" + +void AC_COMMON_API SetProcessPriority(std::string const& logChannel, uint32 affinity, bool highPriority); + +#endif diff --git a/src/server/authserver/Main.cpp b/src/server/authserver/Main.cpp index 620a13512..479efac5f 100644 --- a/src/server/authserver/Main.cpp +++ b/src/server/authserver/Main.cpp @@ -27,6 +27,7 @@ #include "SecretMgr.h" #include "SharedDefines.h" #include "Util.h" +#include "ProcessPriority.h" #include #include #include @@ -35,12 +36,6 @@ #include #include -#ifdef __linux__ -#include -#include -#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 -#endif - #ifndef _ACORE_REALM_CONFIG #define _ACORE_REALM_CONFIG "authserver.conf" #endif @@ -174,73 +169,8 @@ extern int main(int argc, char** argv) signalHandler.handle_signal(SIGBREAK, _handler); #endif -#if defined(_WIN32) || defined(__linux__) - - ///- Handle affinity for multiple processors and process priority - uint32 affinity = sConfigMgr->GetOption("UseProcessors", 0); - bool highPriority = sConfigMgr->GetOption("ProcessPriority", false); - -#ifdef _WIN32 // Windows - - HANDLE hProcess = GetCurrentProcess(); - if (affinity > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) - { - // remove non accessible processors - ULONG_PTR currentAffinity = affinity & appAff; - - if (!currentAffinity) - LOG_ERROR("server.authserver", "server.authserver", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the authserver. Accessible processors bitmask (hex): %x", affinity, appAff); - else if (SetProcessAffinityMask(hProcess, currentAffinity)) - LOG_INFO("server.authserver", "server.authserver", "Using processors (bitmask, hex): %x", currentAffinity); - else - LOG_ERROR("server.authserver", "server.authserver", "Can't set used processors (hex): %x", currentAffinity); - } - } - - if (highPriority) - { - if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) - LOG_INFO("server.authserver", "server.authserver", "authserver process priority class set to HIGH"); - else - LOG_ERROR("server.authserver", "server.authserver", "Can't set authserver process priority class."); - } - -#else // Linux - - if (affinity > 0) - { - cpu_set_t mask; - CPU_ZERO(&mask); - - for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) - if (affinity & (1 << i)) - CPU_SET(i, &mask); - - if (sched_setaffinity(0, sizeof(mask), &mask)) - LOG_ERROR("server.authserver", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); - else - { - CPU_ZERO(&mask); - sched_getaffinity(0, sizeof(mask), &mask); - LOG_INFO("server.authserver", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); - } - } - - if (highPriority) - { - if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) - LOG_ERROR("server.authserver", "Can't set authserver process priority class, error: %s", strerror(errno)); - else - LOG_INFO("server.authserver", "authserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); - } - -#endif -#endif + // Set process priority according to configuration settings + SetProcessPriority("server.authserver", sConfigMgr->GetOption(CONFIG_PROCESSOR_AFFINITY, 0), sConfigMgr->GetOption(CONFIG_HIGH_PRIORITY, false)); // maximum counter for next ping uint32 numLoops = (sConfigMgr->GetOption("MaxPingTime", 30) * (MINUTE * 1000000 / 100000)); diff --git a/src/server/worldserver/Master.cpp b/src/server/worldserver/Master.cpp index 3dcb7a1e8..4e539f6d4 100644 --- a/src/server/worldserver/Master.cpp +++ b/src/server/worldserver/Master.cpp @@ -32,6 +32,7 @@ #include "DatabaseLoader.h" #include "Optional.h" #include "SecretMgr.h" +#include "ProcessPriority.h" #include #ifdef _WIN32 @@ -39,12 +40,6 @@ extern int m_ServiceStatus; #endif -#ifdef __linux__ -#include -#include -#define PROCESS_HIGH_PRIORITY -15 // [-20, 19], default is 0 -#endif - /// Handle worldservers's termination signals void HandleSignal(int sigNum) { @@ -129,6 +124,9 @@ int Master::Run() } } + // Set process priority according to configuration settings + SetProcessPriority("server.worldserver", sConfigMgr->GetOption(CONFIG_PROCESSOR_AFFINITY, 0), sConfigMgr->GetOption(CONFIG_HIGH_PRIORITY, false)); + ///- Start the databases if (!_StartDB()) return 1; @@ -179,74 +177,6 @@ int Master::Run() Acore::Thread auctionLising_thread(new AuctionListingRunnable); auctionLising_thread.setPriority(Acore::Priority_High); -#if defined(_WIN32) || defined(__linux__) - - ///- Handle affinity for multiple processors and process priority - uint32 affinity = sConfigMgr->GetOption("UseProcessors", 0); - bool highPriority = sConfigMgr->GetOption("ProcessPriority", false); - -#ifdef _WIN32 // Windows - - HANDLE hProcess = GetCurrentProcess(); - - if (affinity > 0) - { - ULONG_PTR appAff; - ULONG_PTR sysAff; - - if (GetProcessAffinityMask(hProcess, &appAff, &sysAff)) - { - ULONG_PTR currentAffinity = affinity & appAff; // remove non accessible processors - - if (!currentAffinity) - LOG_ERROR("server", "Processors marked in UseProcessors bitmask (hex) %x are not accessible for the worldserver. Accessible processors bitmask (hex): %x", affinity, appAff); - else if (SetProcessAffinityMask(hProcess, currentAffinity)) - LOG_INFO("server", "Using processors (bitmask, hex): %x", currentAffinity); - else - LOG_ERROR("server", "Can't set used processors (hex): %x", currentAffinity); - } - } - - if (highPriority) - { - if (SetPriorityClass(hProcess, HIGH_PRIORITY_CLASS)) - LOG_INFO("server", "worldserver process priority class set to HIGH"); - else - LOG_ERROR("server", "Can't set worldserver process priority class."); - } - -#else // Linux - - if (affinity > 0) - { - cpu_set_t mask; - CPU_ZERO(&mask); - - for (unsigned int i = 0; i < sizeof(affinity) * 8; ++i) - if (affinity & (1 << i)) - CPU_SET(i, &mask); - - if (sched_setaffinity(0, sizeof(mask), &mask)) - LOG_ERROR("server", "Can't set used processors (hex): %x, error: %s", affinity, strerror(errno)); - else - { - CPU_ZERO(&mask); - sched_getaffinity(0, sizeof(mask), &mask); - LOG_INFO("server", "Using processors (bitmask, hex): %lx", *(__cpu_mask*)(&mask)); - } - } - - if (highPriority) - { - if (setpriority(PRIO_PROCESS, 0, PROCESS_HIGH_PRIORITY)) - LOG_ERROR("server", "Can't set worldserver process priority class, error: %s", strerror(errno)); - else - LOG_INFO("server", "worldserver process priority class set to %i", getpriority(PRIO_PROCESS, 0)); - } - -#endif -#endif - // Start soap serving thread if enabled std::shared_ptr soapThread; if (sConfigMgr->GetOption("SOAP.Enabled", false))