summaryrefslogtreecommitdiff
path: root/src/common/memory_util.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/common/memory_util.cpp')
-rw-r--r--src/common/memory_util.cpp89
1 files changed, 39 insertions, 50 deletions
diff --git a/src/common/memory_util.cpp b/src/common/memory_util.cpp
index 07c7f79c8..c19729b21 100644
--- a/src/common/memory_util.cpp
+++ b/src/common/memory_util.cpp
@@ -2,31 +2,30 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5
6#include "common/logging/log.h" 5#include "common/logging/log.h"
7#include "common/memory_util.h" 6#include "common/memory_util.h"
8 7
9#ifdef _WIN32 8#ifdef _WIN32
10 #include <windows.h> 9#include <windows.h>
11 #include <psapi.h> 10// Windows.h needs to be included before psapi.h
12 #include "common/common_funcs.h" 11#include <psapi.h>
13 #include "common/string_util.h" 12#include "common/common_funcs.h"
13#include "common/string_util.h"
14#else 14#else
15 #include <cstdlib> 15#include <cstdlib>
16 #include <sys/mman.h> 16#include <sys/mman.h>
17#endif 17#endif
18 18
19#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) 19#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT)
20#include <unistd.h> 20#include <unistd.h>
21#define PAGE_MASK (getpagesize() - 1) 21#define PAGE_MASK (getpagesize() - 1)
22#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK)) 22#define round_page(x) ((((unsigned long)(x)) + PAGE_MASK) & ~(PAGE_MASK))
23#endif 23#endif
24 24
25// This is purposely not a full wrapper for virtualalloc/mmap, but it 25// This is purposely not a full wrapper for virtualalloc/mmap, but it
26// provides exactly the primitive operations that Dolphin needs. 26// provides exactly the primitive operations that Dolphin needs.
27 27
28void* AllocateExecutableMemory(size_t size, bool low) 28void* AllocateExecutableMemory(size_t size, bool low) {
29{
30#if defined(_WIN32) 29#if defined(_WIN32)
31 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE); 30 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
32#else 31#else
@@ -39,31 +38,27 @@ void* AllocateExecutableMemory(size_t size, bool low)
39 // effect of discarding already mapped pages that happen to be in the 38 // effect of discarding already mapped pages that happen to be in the
40 // requested virtual memory range (such as the emulated RAM, sometimes). 39 // requested virtual memory range (such as the emulated RAM, sometimes).
41 if (low && (!map_hint)) 40 if (low && (!map_hint))
42 map_hint = (char*)round_page(512*1024*1024); /* 0.5 GB rounded up to the next page */ 41 map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
43#endif 42#endif
44 void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, 43 void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE
45 MAP_ANON | MAP_PRIVATE
46#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT) 44#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT)
47 | (low ? MAP_32BIT : 0) 45 | (low ? MAP_32BIT : 0)
48#endif 46#endif
49 , -1, 0); 47 ,
48 -1, 0);
50#endif /* defined(_WIN32) */ 49#endif /* defined(_WIN32) */
51 50
52#ifdef _WIN32 51#ifdef _WIN32
53 if (ptr == nullptr) 52 if (ptr == nullptr) {
54 {
55#else 53#else
56 if (ptr == MAP_FAILED) 54 if (ptr == MAP_FAILED) {
57 {
58 ptr = nullptr; 55 ptr = nullptr;
59#endif 56#endif
60 LOG_ERROR(Common_Memory, "Failed to allocate executable memory"); 57 LOG_ERROR(Common_Memory, "Failed to allocate executable memory");
61 } 58 }
62#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT) 59#if !defined(_WIN32) && defined(ARCHITECTURE_X64) && !defined(MAP_32BIT)
63 else 60 else {
64 { 61 if (low) {
65 if (low)
66 {
67 map_hint += size; 62 map_hint += size;
68 map_hint = (char*)round_page(map_hint); /* round up to the next page */ 63 map_hint = (char*)round_page(map_hint); /* round up to the next page */
69 } 64 }
@@ -78,13 +73,11 @@ void* AllocateExecutableMemory(size_t size, bool low)
78 return ptr; 73 return ptr;
79} 74}
80 75
81void* AllocateMemoryPages(size_t size) 76void* AllocateMemoryPages(size_t size) {
82{
83#ifdef _WIN32 77#ifdef _WIN32
84 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); 78 void* ptr = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
85#else 79#else
86 void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, 80 void* ptr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
87 MAP_ANON | MAP_PRIVATE, -1, 0);
88 81
89 if (ptr == MAP_FAILED) 82 if (ptr == MAP_FAILED)
90 ptr = nullptr; 83 ptr = nullptr;
@@ -96,10 +89,9 @@ void* AllocateMemoryPages(size_t size)
96 return ptr; 89 return ptr;
97} 90}
98 91
99void* AllocateAlignedMemory(size_t size,size_t alignment) 92void* AllocateAlignedMemory(size_t size, size_t alignment) {
100{
101#ifdef _WIN32 93#ifdef _WIN32
102 void* ptr = _aligned_malloc(size,alignment); 94 void* ptr = _aligned_malloc(size, alignment);
103#else 95#else
104 void* ptr = nullptr; 96 void* ptr = nullptr;
105#ifdef ANDROID 97#ifdef ANDROID
@@ -116,10 +108,8 @@ void* AllocateAlignedMemory(size_t size,size_t alignment)
116 return ptr; 108 return ptr;
117} 109}
118 110
119void FreeMemoryPages(void* ptr, size_t size) 111void FreeMemoryPages(void* ptr, size_t size) {
120{ 112 if (ptr) {
121 if (ptr)
122 {
123#ifdef _WIN32 113#ifdef _WIN32
124 if (!VirtualFree(ptr, 0, MEM_RELEASE)) 114 if (!VirtualFree(ptr, 0, MEM_RELEASE))
125 LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n%s", GetLastErrorMsg()); 115 LOG_ERROR(Common_Memory, "FreeMemoryPages failed!\n%s", GetLastErrorMsg());
@@ -129,20 +119,17 @@ void FreeMemoryPages(void* ptr, size_t size)
129 } 119 }
130} 120}
131 121
132void FreeAlignedMemory(void* ptr) 122void FreeAlignedMemory(void* ptr) {
133{ 123 if (ptr) {
134 if (ptr)
135 {
136#ifdef _WIN32 124#ifdef _WIN32
137 _aligned_free(ptr); 125 _aligned_free(ptr);
138#else 126#else
139 free(ptr); 127 free(ptr);
140#endif 128#endif
141 } 129 }
142} 130}
143 131
144void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) 132void WriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
145{
146#ifdef _WIN32 133#ifdef _WIN32
147 DWORD oldValue; 134 DWORD oldValue;
148 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue)) 135 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READ : PAGE_READONLY, &oldValue))
@@ -152,19 +139,19 @@ void WriteProtectMemory(void* ptr, size_t size, bool allowExecute)
152#endif 139#endif
153} 140}
154 141
155void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) 142void UnWriteProtectMemory(void* ptr, size_t size, bool allowExecute) {
156{
157#ifdef _WIN32 143#ifdef _WIN32
158 DWORD oldValue; 144 DWORD oldValue;
159 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE, &oldValue)) 145 if (!VirtualProtect(ptr, size, allowExecute ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE,
146 &oldValue))
160 LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n%s", GetLastErrorMsg()); 147 LOG_ERROR(Common_Memory, "UnWriteProtectMemory failed!\n%s", GetLastErrorMsg());
161#else 148#else
162 mprotect(ptr, size, allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ); 149 mprotect(ptr, size,
150 allowExecute ? (PROT_READ | PROT_WRITE | PROT_EXEC) : PROT_WRITE | PROT_READ);
163#endif 151#endif
164} 152}
165 153
166std::string MemUsage() 154std::string MemUsage() {
167{
168#ifdef _WIN32 155#ifdef _WIN32
169#pragma comment(lib, "psapi") 156#pragma comment(lib, "psapi")
170 DWORD processID = GetCurrentProcessId(); 157 DWORD processID = GetCurrentProcessId();
@@ -175,10 +162,12 @@ std::string MemUsage()
175 // Print information about the memory usage of the process. 162 // Print information about the memory usage of the process.
176 163
177 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID); 164 hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processID);
178 if (nullptr == hProcess) return "MemUsage Error"; 165 if (nullptr == hProcess)
166 return "MemUsage Error";
179 167
180 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc))) 168 if (GetProcessMemoryInfo(hProcess, &pmc, sizeof(pmc)))
181 Ret = Common::StringFromFormat("%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str()); 169 Ret = Common::StringFromFormat(
170 "%s K", Common::ThousandSeparate(pmc.WorkingSetSize / 1024, 7).c_str());
182 171
183 CloseHandle(hProcess); 172 CloseHandle(hProcess);
184 return Ret; 173 return Ret;