Class Mem replaced to VirtualMemory.

This commit is contained in:
XMRig 2019-07-17 04:57:58 +07:00
parent 20313cbc56
commit 2bf5ffb2df
12 changed files with 147 additions and 384 deletions

View file

@ -34,7 +34,6 @@ set(HEADERS
src/core/config/usage.h
src/core/Controller.h
src/core/Miner.h
src/Mem.h
src/net/interfaces/IJobResultListener.h
src/net/JobResult.h
src/net/JobResults.h
@ -85,7 +84,6 @@ set(SOURCES
src/core/config/ConfigTransform.cpp
src/core/Controller.cpp
src/core/Miner.cpp
src/Mem.cpp
src/net/JobResults.cpp
src/net/Network.cpp
src/net/NetworkState.cpp
@ -113,7 +111,6 @@ if (WIN32)
"${SOURCES_OS}"
res/app.rc
src/App_win.cpp
src/Mem_win.cpp
src/crypto/common/VirtualMemory_win.cpp
)
@ -123,14 +120,12 @@ elseif (APPLE)
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/Mem_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)
else()
set(SOURCES_OS
"${SOURCES_OS}"
src/App_unix.cpp
src/Mem_unix.cpp
src/crypto/common/VirtualMemory_unix.cpp
)

View file

@ -37,7 +37,7 @@
#include "core/config/Config.h"
#include "core/Controller.h"
#include "core/Miner.h"
#include "Mem.h"
#include "crypto/common/VirtualMemory.h"
#include "net/Network.h"
#include "Summary.h"
#include "version.h"
@ -76,7 +76,7 @@ int xmrig::App::exec()
background();
Mem::init(m_controller->config()->cpu().isHugePages());
VirtualMemory::init(m_controller->config()->cpu().isHugePages());
Summary::print(m_controller);

View file

@ -1,31 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "Mem.h"
bool Mem::m_enabled = true;
int Mem::m_flags = 0;

View file

@ -1,72 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef XMRIG_MEM_H
#define XMRIG_MEM_H
#include <stddef.h>
#include <stdint.h>
#include "crypto/cn/CnAlgo.h"
struct cryptonight_ctx;
struct MemInfo
{
alignas(16) uint8_t *memory = nullptr;
size_t hugePages = 0;
size_t pages = 0;
size_t size = 0;
};
class Mem
{
public:
enum Flags {
HugepagesAvailable = 1,
HugepagesEnabled = 2,
Lock = 4
};
static void init(bool enabled);
static inline bool isHugepagesAvailable() { return (m_flags & HugepagesAvailable) != 0; }
private:
static void allocate(MemInfo &info, bool enabled);
static void release(MemInfo &info);
static int m_flags;
static bool m_enabled;
};
#endif /* XMRIG_MEM_H */

View file

@ -1,88 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <sys/mman.h>
#include "base/io/log/Log.h"
#include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#include "crypto/cn/CryptoNight.h"
#include "Mem.h"
#if defined(__APPLE__)
# include <mach/vm_statistics.h>
#endif
void Mem::init(bool enabled)
{
m_enabled = enabled;
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
if (!enabled) {
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
return;
}
info.memory = static_cast<uint8_t*>(xmrig::VirtualMemory::allocateLargePagesMemory(info.size));
if (!info.memory) {
return allocate(info, false);;
}
info.hugePages = info.pages;
if (madvise(info.memory, info.size, MADV_RANDOM | MADV_WILLNEED) != 0) {
LOG_ERR("madvise failed");
}
if (mlock(info.memory, info.size) == 0) {
m_flags |= Lock;
}
}
void Mem::release(MemInfo &info)
{
if (info.hugePages) {
if (m_flags & Lock) {
munlock(info.memory, info.size);
}
xmrig::VirtualMemory::freeLargePagesMemory(info.memory, info.size);
}
else {
_mm_free(info.memory);
}
}

View file

@ -1,184 +0,0 @@
/* XMRig
* Copyright 2010 Jeff Garzik <jgarzik@pobox.com>
* Copyright 2012-2014 pooler <pooler@litecoinpool.org>
* Copyright 2014 Lucas Jones <https://github.com/lucasjones>
* Copyright 2014-2016 Wolf9466 <https://github.com/OhGodAPet>
* Copyright 2016 Jay D Dee <jayddee246@gmail.com>
* Copyright 2017-2018 XMR-Stak <https://github.com/fireice-uk>, <https://github.com/psychocrypt>
* Copyright 2018 Lee Clagett <https://github.com/vtnerd>
* Copyright 2018-2019 SChernykh <https://github.com/SChernykh>
* Copyright 2016-2019 XMRig <https://github.com/xmrig>, <support@xmrig.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <winsock2.h>
#include <windows.h>
#include <ntsecapi.h>
#include <tchar.h>
#include "base/io/log/Log.h"
#include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
#include "crypto/cn/CryptoNight.h"
#include "Mem.h"
/*****************************************************************
SetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.
Inputs:
HANDLE hProcess: Handle for the process for which the
privilege is needed
BOOL bEnable: Enable (TRUE) or disable?
Return value: TRUE indicates success, FALSE failure.
*****************************************************************/
/**
* AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx
* Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx
*/
static BOOL SetLockPagesPrivilege() {
HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) {
return FALSE;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
return FALSE;
}
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr);
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
return FALSE;
}
CloseHandle(token);
return TRUE;
}
static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
LSA_UNICODE_STRING lsaString;
DWORD dwLen = (DWORD) wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
static BOOL ObtainLockPagesPrivilege() {
HANDLE token;
PTOKEN_USER user = nullptr;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
DWORD size = 0;
GetTokenInformation(token, TokenUser, nullptr, 0, &size);
if (size) {
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
}
GetTokenInformation(token, TokenUser, user, size, &size);
CloseHandle(token);
}
if (!user) {
return FALSE;
}
LSA_HANDLE handle;
LSA_OBJECT_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
BOOL result = FALSE;
if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it");
result = TRUE;
}
LsaClose(handle);
}
LocalFree(user);
return result;
}
static BOOL TrySetLockPagesPrivilege() {
if (SetLockPagesPrivilege()) {
return TRUE;
}
return ObtainLockPagesPrivilege() && SetLockPagesPrivilege();
}
void Mem::init(bool enabled)
{
m_enabled = enabled;
if (enabled && TrySetLockPagesPrivilege()) {
m_flags |= HugepagesAvailable;
}
}
void Mem::allocate(MemInfo &info, bool enabled)
{
info.hugePages = 0;
if (!enabled) {
info.memory = static_cast<uint8_t*>(_mm_malloc(info.size, 4096));
return;
}
info.memory = static_cast<uint8_t*>(xmrig::VirtualMemory::allocateLargePagesMemory(info.size));
if (info.memory) {
info.hugePages = info.pages;
return;
}
allocate(info, false);
}
void Mem::release(MemInfo &info)
{
if (info.hugePages) {
xmrig::VirtualMemory::freeLargePagesMemory(info.memory, info.size);
}
else {
_mm_free(info.memory);
}
}

View file

@ -34,7 +34,7 @@
#include "core/config/Config.h"
#include "core/Controller.h"
#include "crypto/common/Assembly.h"
#include "Mem.h"
#include "crypto/common/VirtualMemory.h"
#include "Summary.h"
#include "version.h"
@ -59,7 +59,7 @@ inline static const char *asmName(xmrig::Assembly::Id assembly)
static void print_memory(xmrig::Config *) {
# ifdef _WIN32
xmrig::Log::print(GREEN_BOLD(" * ") WHITE_BOLD("%-13s") "%s",
"HUGE PAGES", Mem::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
"HUGE PAGES", xmrig::VirtualMemory::isHugepagesAvailable() ? GREEN_BOLD("available") : RED_BOLD("unavailable"));
# endif
}

View file

@ -27,6 +27,7 @@
#include <stdint.h>
#include <stddef.h>
namespace xmrig {

View file

@ -23,6 +23,7 @@
*/
#include <algorithm>
#include <uv.h>

View file

@ -51,9 +51,11 @@ public:
static void *allocateLargePagesMemory(size_t size);
static void flushInstructionCache(void *p, size_t size);
static void freeLargePagesMemory(void *p, size_t size);
static void init(bool hugePages);
static void protectExecutableMemory(void *p, size_t size);
static void unprotectExecutableMemory(void *p, size_t size);
static inline bool isHugepagesAvailable() { return (m_globalFlags & HUGEPAGES_AVAILABLE) != 0; }
static inline constexpr size_t align(size_t pos, size_t align = 2097152) { return ((pos - 1) / align + 1) * align; }
private:
@ -63,6 +65,8 @@ private:
LOCK = 4
};
static int m_globalFlags;
int m_flags = 0;
size_t m_size = 0;
uint8_t *m_scratchpad = nullptr;

View file

@ -38,6 +38,9 @@
#endif
int xmrig::VirtualMemory::m_globalFlags = 0;
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) :
m_size(VirtualMemory::align(size))
{
@ -120,6 +123,14 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t size)
}
void xmrig::VirtualMemory::init(bool hugePages)
{
if (hugePages) {
m_globalFlags = HUGEPAGES | HUGEPAGES_AVAILABLE;
}
}
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
{
mprotect(p, size, PROT_READ | PROT_EXEC);

View file

@ -27,11 +27,123 @@
#include <winsock2.h>
#include <windows.h>
#include <ntsecapi.h>
#include <tchar.h>
#include "base/io/log/Log.h"
#include "crypto/common/portable/mm_malloc.h"
#include "crypto/common/VirtualMemory.h"
/*****************************************************************
SetLockPagesPrivilege: a function to obtain or
release the privilege of locking physical pages.
Inputs:
HANDLE hProcess: Handle for the process for which the
privilege is needed
BOOL bEnable: Enable (TRUE) or disable?
Return value: TRUE indicates success, FALSE failure.
*****************************************************************/
/**
* AWE Example: https://msdn.microsoft.com/en-us/library/windows/desktop/aa366531(v=vs.85).aspx
* Creating a File Mapping Using Large Pages: https://msdn.microsoft.com/en-us/library/aa366543(VS.85).aspx
*/
static BOOL SetLockPagesPrivilege() {
HANDLE token;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &token) != TRUE) {
return FALSE;
}
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
if (LookupPrivilegeValue(nullptr, SE_LOCK_MEMORY_NAME, &(tp.Privileges[0].Luid)) != TRUE) {
return FALSE;
}
BOOL rc = AdjustTokenPrivileges(token, FALSE, (PTOKEN_PRIVILEGES) &tp, 0, nullptr, nullptr);
if (rc != TRUE || GetLastError() != ERROR_SUCCESS) {
return FALSE;
}
CloseHandle(token);
return TRUE;
}
static LSA_UNICODE_STRING StringToLsaUnicodeString(LPCTSTR string) {
LSA_UNICODE_STRING lsaString;
DWORD dwLen = (DWORD) wcslen(string);
lsaString.Buffer = (LPWSTR) string;
lsaString.Length = (USHORT)((dwLen) * sizeof(WCHAR));
lsaString.MaximumLength = (USHORT)((dwLen + 1) * sizeof(WCHAR));
return lsaString;
}
static BOOL ObtainLockPagesPrivilege() {
HANDLE token;
PTOKEN_USER user = nullptr;
if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &token) == TRUE) {
DWORD size = 0;
GetTokenInformation(token, TokenUser, nullptr, 0, &size);
if (size) {
user = (PTOKEN_USER) LocalAlloc(LPTR, size);
}
GetTokenInformation(token, TokenUser, user, size, &size);
CloseHandle(token);
}
if (!user) {
return FALSE;
}
LSA_HANDLE handle;
LSA_OBJECT_ATTRIBUTES attributes;
ZeroMemory(&attributes, sizeof(attributes));
BOOL result = FALSE;
if (LsaOpenPolicy(nullptr, &attributes, POLICY_ALL_ACCESS, &handle) == 0) {
LSA_UNICODE_STRING str = StringToLsaUnicodeString(_T(SE_LOCK_MEMORY_NAME));
if (LsaAddAccountRights(handle, user->User.Sid, &str, 1) == 0) {
LOG_NOTICE("Huge pages support was successfully enabled, but reboot required to use it");
result = TRUE;
}
LsaClose(handle);
}
LocalFree(user);
return result;
}
static BOOL TrySetLockPagesPrivilege() {
if (SetLockPagesPrivilege()) {
return TRUE;
}
return ObtainLockPagesPrivilege() && SetLockPagesPrivilege();
}
int xmrig::VirtualMemory::m_globalFlags = 0;
xmrig::VirtualMemory::VirtualMemory(size_t size, bool hugePages, size_t align) :
m_size(VirtualMemory::align(size))
{
@ -94,6 +206,20 @@ void xmrig::VirtualMemory::freeLargePagesMemory(void *p, size_t)
}
void xmrig::VirtualMemory::init(bool hugePages)
{
if (!hugePages) {
return;
}
m_globalFlags = HUGEPAGES;
if (TrySetLockPagesPrivilege()) {
m_globalFlags |= HUGEPAGES_AVAILABLE;
}
}
void xmrig::VirtualMemory::protectExecutableMemory(void *p, size_t size)
{
DWORD oldProtect;