CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
hrydgard

CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!

GitHub Repository: hrydgard/ppsspp
Path: blob/master/Common/MemArenaDarwin.cpp
Views: 1401
1
// Copyright (C) 2003 Dolphin Project.
2
3
// This program is free software: you can redistribute it and/or modify
4
// it under the terms of the GNU General Public License as published by
5
// the Free Software Foundation, version 2.0 or later versions.
6
7
// This program is distributed in the hope that it will be useful,
8
// but WITHOUT ANY WARRANTY; without even the implied warranty of
9
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
// GNU General Public License 2.0 for more details.
11
12
// A copy of the GPL 2.0 should have been included with the program.
13
// If not, see http://www.gnu.org/licenses/
14
15
// Official SVN repository and contact information can be found at
16
// http://code.google.com/p/dolphin-emu/
17
18
#include "ppsspp_config.h"
19
20
#if defined(__APPLE__)
21
22
#include <cstdint>
23
#include <sys/stat.h>
24
#include <fcntl.h>
25
#include <unistd.h>
26
#include <cerrno>
27
#include <cstring>
28
29
#include <mach/mach.h>
30
#include <mach/vm_map.h>
31
32
#include "Common/Log.h"
33
#include "Common/File/FileUtil.h"
34
#include "Common/MemoryUtil.h"
35
#include "Common/MemArena.h"
36
37
size_t MemArena::roundup(size_t x) {
38
return x;
39
}
40
41
bool MemArena::GrabMemSpace(size_t size) {
42
vm_size = size;
43
kern_return_t retval = vm_allocate(mach_task_self(), &vm_mem, size, VM_FLAGS_ANYWHERE);
44
if (retval != KERN_SUCCESS) {
45
ERROR_LOG(Log::MemMap, "Failed to grab a block of virtual memory");
46
return false;
47
} else {
48
INFO_LOG(Log::MemMap, "Successfully allocated %d bytes at %p", (int)size, (void *)vm_mem);
49
return true;
50
}
51
}
52
53
void MemArena::ReleaseSpace() {
54
vm_deallocate(mach_task_self(), vm_mem, vm_size);
55
vm_size = 0;
56
vm_mem = 0;
57
}
58
59
void *MemArena::CreateView(s64 offset, size_t size, void *base) {
60
mach_port_t self = mach_task_self();
61
vm_address_t target = (vm_address_t)base;
62
uint64_t mask = 0;
63
bool anywhere = false;
64
vm_address_t source = vm_mem + offset;
65
vm_prot_t cur_protection = 0;
66
vm_prot_t max_protection = 0;
67
kern_return_t retval =
68
vm_remap(self, &target, size, mask, anywhere,
69
self, source, false,
70
&cur_protection, &max_protection, VM_INHERIT_DEFAULT);
71
if (retval != KERN_SUCCESS) {
72
// 1 == KERN_INVALID_ADDRESS
73
// 3 == KERN_NO_SPACE (race?)
74
// 4 == KERN_INVALID_ARGUMENT
75
ERROR_LOG(Log::MemMap, "vm_remap failed (%d) - could not remap from %llx (offset %llx) of size %llx to %p",
76
(int)retval, (uint64_t)source, (uint64_t)offset, (uint64_t)size, base);
77
return nullptr;
78
}
79
return (void *)target;
80
}
81
82
void MemArena::ReleaseView(s64 offset, void* view, size_t size) {
83
vm_address_t addr = (vm_address_t)view;
84
vm_deallocate(mach_task_self(), addr, size);
85
}
86
87
bool MemArena::NeedsProbing() {
88
#if PPSSPP_PLATFORM(IOS) && PPSSPP_ARCH(64BIT)
89
return true;
90
#else
91
return false;
92
#endif
93
}
94
95
u8* MemArena::Find4GBBase() {
96
#if PPSSPP_PLATFORM(IOS) && PPSSPP_ARCH(64BIT)
97
// The caller will need to do probing, like on 32-bit Windows.
98
return nullptr;
99
#else
100
size_t size;
101
#if PPSSPP_ARCH(64BIT)
102
size = 0xE1000000;
103
#else
104
size = 0x10000000;
105
#endif
106
107
vm_address_t addr = 0;
108
kern_return_t retval = vm_allocate(mach_task_self(), &addr, size, VM_FLAGS_ANYWHERE);
109
if (retval == KERN_SUCCESS) {
110
// Don't need the memory now, was just probing.
111
vm_deallocate(mach_task_self(), addr, size);
112
return (u8 *)addr;
113
}
114
#endif
115
return nullptr;
116
}
117
118
#endif // __APPLE__
119
120