Unified memory allocation functions.

This commit is contained in:
XMRig 2019-08-02 14:44:38 +07:00
parent 718be7e9aa
commit bdaf28adf8

View file

@ -26,80 +26,33 @@ OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/ */
#include "virtual_memory.hpp"
#include <stdexcept> #include <stdexcept>
#if defined(_WIN32) || defined(__CYGWIN__)
#include <windows.h>
#else
#ifdef __APPLE__
#include <mach/vm_statistics.h>
#endif
#include <sys/types.h>
#include <sys/mman.h>
#ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON
#endif
#endif
#if defined(_WIN32) || defined(__CYGWIN__) #include "crypto/common/VirtualMemory.h"
std::string getErrorMessage(const char* function) { #include "virtual_memory.hpp"
LPSTR messageBuffer = nullptr;
size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
NULL, GetLastError(), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);
std::string message(messageBuffer, size);
LocalFree(messageBuffer);
return std::string(function) + std::string(": ") + message;
}
#endif
void* allocExecutableMemory(std::size_t bytes) { void* allocExecutableMemory(std::size_t bytes) {
void* mem; void *mem = xmrig::VirtualMemory::allocateExecutableMemory(bytes);
#if defined(_WIN32) || defined(__CYGWIN__) if (mem == nullptr) {
mem = VirtualAlloc(nullptr, bytes, MEM_COMMIT, PAGE_EXECUTE_READWRITE); throw std::runtime_error("Failed to allocate executable memory");
if (mem == nullptr) }
throw std::runtime_error(getErrorMessage("allocExecutableMemory - VirtualAlloc"));
#else return mem;
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
if (mem == MAP_FAILED)
throw std::runtime_error("allocExecutableMemory - mmap failed");
#endif
return mem;
} }
constexpr std::size_t align(std::size_t pos, std::size_t align) {
return ((pos - 1) / align + 1) * align;
}
void* allocLargePagesMemory(std::size_t bytes) { void* allocLargePagesMemory(std::size_t bytes) {
void* mem; void *mem = xmrig::VirtualMemory::allocateLargePagesMemory(bytes);
#if defined(_WIN32) || defined(__CYGWIN__) if (mem == nullptr) {
auto pageMinimum = GetLargePageMinimum(); throw std::runtime_error("Failed to allocate large pages memory");
if (pageMinimum > 0) }
mem = VirtualAlloc(NULL, align(bytes, pageMinimum), MEM_COMMIT | MEM_RESERVE | MEM_LARGE_PAGES, PAGE_READWRITE);
else return mem;
throw std::runtime_error("allocLargePagesMemory - Large pages are not supported");
if (mem == nullptr)
throw std::runtime_error(getErrorMessage("allocLargePagesMemory - VirtualAlloc"));
#else
#ifdef __APPLE__
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_FLAGS_SUPERPAGE_SIZE_2MB, 0);
#elif defined(__FreeBSD__)
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0);
#else
mem = mmap(nullptr, bytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_HUGETLB | MAP_POPULATE, -1, 0);
#endif
if (mem == MAP_FAILED)
throw std::runtime_error("allocLargePagesMemory - mmap failed");
#endif
return mem;
} }
void freePagedMemory(void* ptr, std::size_t bytes) { void freePagedMemory(void* ptr, std::size_t bytes) {
#if defined(_WIN32) || defined(__CYGWIN__) xmrig::VirtualMemory::freeLargePagesMemory(ptr, bytes);
VirtualFree(ptr, 0, MEM_RELEASE);
#else
munmap(ptr, bytes);
#endif
} }