|
|
@@ -449,21 +449,52 @@ private:
|
|
|
int fd{-1}; // memfd file descriptor, -1 is the error value of memfd_create
|
|
|
};
|
|
|
|
|
|
-#else // ^^^ Linux ^^^
|
|
|
+#else // ^^^ Linux ^^^ vvv Generic vvv
|
|
|
|
|
|
-#error Please implement the host memory for your platform
|
|
|
+class HostMemory::Impl {
|
|
|
+public:
|
|
|
+ explicit Impl(size_t /*backing_size */, size_t /* virtual_size */) {
|
|
|
+ // This is just a place holder.
|
|
|
+ // Please implement fastmem in a propper way on your platform.
|
|
|
+ throw std::bad_alloc{};
|
|
|
+ }
|
|
|
|
|
|
-#endif
|
|
|
+ void Map(size_t virtual_offset, size_t host_offset, size_t length) {}
|
|
|
+
|
|
|
+ void Unmap(size_t virtual_offset, size_t length) {}
|
|
|
+
|
|
|
+ void Protect(size_t virtual_offset, size_t length, bool read, bool write) {}
|
|
|
+
|
|
|
+ u8* backing_base{nullptr};
|
|
|
+ u8* virtual_base{nullptr};
|
|
|
+};
|
|
|
+
|
|
|
+#endif // ^^^ Generic ^^^
|
|
|
|
|
|
HostMemory::HostMemory(size_t backing_size_, size_t virtual_size_)
|
|
|
- : backing_size(backing_size_),
|
|
|
- virtual_size(virtual_size_), impl{std::make_unique<HostMemory::Impl>(
|
|
|
- AlignUp(backing_size, PageAlignment),
|
|
|
- AlignUp(virtual_size, PageAlignment) + 3 * HugePageSize)},
|
|
|
- backing_base{impl->backing_base}, virtual_base{impl->virtual_base} {
|
|
|
- virtual_base += 2 * HugePageSize - 1;
|
|
|
- virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1);
|
|
|
- virtual_base_offset = virtual_base - impl->virtual_base;
|
|
|
+ : backing_size(backing_size_), virtual_size(virtual_size_) {
|
|
|
+ try {
|
|
|
+ // Try to allocate a fastmem arena.
|
|
|
+ // The implementation will fail with std::bad_alloc on errors.
|
|
|
+ impl = std::make_unique<HostMemory::Impl>(AlignUp(backing_size, PageAlignment),
|
|
|
+ AlignUp(virtual_size, PageAlignment) +
|
|
|
+ 3 * HugePageSize);
|
|
|
+ backing_base = impl->backing_base;
|
|
|
+ virtual_base = impl->virtual_base;
|
|
|
+
|
|
|
+ if (virtual_base) {
|
|
|
+ virtual_base += 2 * HugePageSize - 1;
|
|
|
+ virtual_base -= reinterpret_cast<size_t>(virtual_base) & (HugePageSize - 1);
|
|
|
+ virtual_base_offset = virtual_base - impl->virtual_base;
|
|
|
+ }
|
|
|
+
|
|
|
+ } catch (const std::bad_alloc&) {
|
|
|
+ LOG_CRITICAL(HW_Memory,
|
|
|
+ "Fastmem unavailable, falling back to VirtualBuffer for memory allocation");
|
|
|
+ fallback_buffer = std::make_unique<Common::VirtualBuffer<u8>>(backing_size);
|
|
|
+ backing_base = fallback_buffer->data();
|
|
|
+ virtual_base = nullptr;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
HostMemory::~HostMemory() = default;
|
|
|
@@ -478,7 +509,7 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length) {
|
|
|
ASSERT(length % PageAlignment == 0);
|
|
|
ASSERT(virtual_offset + length <= virtual_size);
|
|
|
ASSERT(host_offset + length <= backing_size);
|
|
|
- if (length == 0) {
|
|
|
+ if (length == 0 || !virtual_base || !impl) {
|
|
|
return;
|
|
|
}
|
|
|
impl->Map(virtual_offset + virtual_base_offset, host_offset, length);
|
|
|
@@ -488,7 +519,7 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length) {
|
|
|
ASSERT(virtual_offset % PageAlignment == 0);
|
|
|
ASSERT(length % PageAlignment == 0);
|
|
|
ASSERT(virtual_offset + length <= virtual_size);
|
|
|
- if (length == 0) {
|
|
|
+ if (length == 0 || !virtual_base || !impl) {
|
|
|
return;
|
|
|
}
|
|
|
impl->Unmap(virtual_offset + virtual_base_offset, length);
|
|
|
@@ -498,7 +529,7 @@ void HostMemory::Protect(size_t virtual_offset, size_t length, bool read, bool w
|
|
|
ASSERT(virtual_offset % PageAlignment == 0);
|
|
|
ASSERT(length % PageAlignment == 0);
|
|
|
ASSERT(virtual_offset + length <= virtual_size);
|
|
|
- if (length == 0) {
|
|
|
+ if (length == 0 || !virtual_base || !impl) {
|
|
|
return;
|
|
|
}
|
|
|
impl->Protect(virtual_offset + virtual_base_offset, length, read, write);
|