Moving mmap to poly, cleaning up devices.
This commit is contained in:
46
src/poly/mapped_memory.h
Normal file
46
src/poly/mapped_memory.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef POLY_MAPPED_MEMORY_H_
|
||||
#define POLY_MAPPED_MEMORY_H_
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
namespace poly {
|
||||
|
||||
class MappedMemory {
|
||||
public:
|
||||
enum class Mode {
|
||||
READ,
|
||||
READ_WRITE,
|
||||
};
|
||||
|
||||
virtual ~MappedMemory() = default;
|
||||
|
||||
static std::unique_ptr<MappedMemory> Open(const std::wstring& path, Mode mode,
|
||||
size_t offset = 0,
|
||||
size_t length = 0);
|
||||
|
||||
uint8_t* data() const { return reinterpret_cast<uint8_t*>(data_); }
|
||||
size_t size() const { return size_; }
|
||||
|
||||
protected:
|
||||
MappedMemory(const std::wstring& path, Mode mode)
|
||||
: path_(path), mode_(mode), data_(nullptr), size_(0) {}
|
||||
|
||||
std::wstring path_;
|
||||
Mode mode_;
|
||||
void* data_;
|
||||
size_t size_;
|
||||
};
|
||||
|
||||
} // namespace poly
|
||||
|
||||
#endif // POLY_MAPPED_MEMORY_H_
|
||||
77
src/poly/mapped_memory_posix.cc
Normal file
77
src/poly/mapped_memory_posix.cc
Normal file
@@ -0,0 +1,77 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <poly/mapped_memory.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
#include <cstdio>
|
||||
|
||||
#include <poly/string.h>
|
||||
|
||||
namespace poly {
|
||||
|
||||
class PosixMappedMemory : public MappedMemory {
|
||||
public:
|
||||
PosixMappedMemory(const std::wstring& path, Mode mode)
|
||||
: MappedMemory(path, mode), file_handle(nullptr) {}
|
||||
|
||||
~PosixMappedMemory() override {
|
||||
if (data_) {
|
||||
munmap(data_, size_);
|
||||
}
|
||||
if (file_handle) {
|
||||
fclose(file_handle);
|
||||
}
|
||||
}
|
||||
|
||||
FILE* file_handle;
|
||||
};
|
||||
|
||||
std::unique_ptr<MappedMemory> MappedMemory::Open(const std::wstring& path,
|
||||
Mode mode, size_t offset,
|
||||
size_t length) {
|
||||
const char* mode;
|
||||
int prot;
|
||||
switch (mode) {
|
||||
case Mode::READ:
|
||||
mode = "rb";
|
||||
prot = PROT_READ;
|
||||
break;
|
||||
case Mode::READ_WRITE:
|
||||
mode = "r+b";
|
||||
prot = PROT_READ | PROT_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
auto mm = std::make_unique<PosixMappedMemory>(path, mode);
|
||||
|
||||
mm->file_handle = fopen(poly::to_string(path).c_str(), mode);
|
||||
if (!mm->file_handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
size_t map_length;
|
||||
map_length = length;
|
||||
if (!length) {
|
||||
fseeko(mm->file_handle, 0, SEEK_END);
|
||||
map_length = ftello(mm->file_handle);
|
||||
fseeko(mm->file_handle, 0, SEEK_SET);
|
||||
}
|
||||
mm->size_ = map_length;
|
||||
|
||||
mm->data_ =
|
||||
mmap(0, map_length, prot, MAP_SHARED, fileno(mm->file_handle), offset);
|
||||
if (!mm->data_) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return std::move(mm);
|
||||
}
|
||||
|
||||
} // namespace poly
|
||||
105
src/poly/mapped_memory_win.cc
Normal file
105
src/poly/mapped_memory_win.cc
Normal file
@@ -0,0 +1,105 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2014 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <poly/mapped_memory.h>
|
||||
|
||||
#include <Windows.h>
|
||||
|
||||
namespace poly {
|
||||
|
||||
class Win32MappedMemory : public MappedMemory {
|
||||
public:
|
||||
Win32MappedMemory(const std::wstring& path, Mode mode)
|
||||
: MappedMemory(path, mode),
|
||||
file_handle(nullptr),
|
||||
mapping_handle(nullptr) {}
|
||||
|
||||
~Win32MappedMemory() override {
|
||||
if (data_) {
|
||||
UnmapViewOfFile(data_);
|
||||
}
|
||||
if (mapping_handle) {
|
||||
CloseHandle(mapping_handle);
|
||||
}
|
||||
if (file_handle) {
|
||||
CloseHandle(file_handle);
|
||||
}
|
||||
}
|
||||
|
||||
HANDLE file_handle;
|
||||
HANDLE mapping_handle;
|
||||
};
|
||||
|
||||
std::unique_ptr<MappedMemory> MappedMemory::Open(const std::wstring& path,
|
||||
Mode mode, size_t offset,
|
||||
size_t length) {
|
||||
DWORD file_access = 0;
|
||||
DWORD file_share = 0;
|
||||
DWORD create_mode = 0;
|
||||
DWORD mapping_protect = 0;
|
||||
DWORD view_access = 0;
|
||||
switch (mode) {
|
||||
case Mode::READ:
|
||||
file_access |= GENERIC_READ;
|
||||
file_share |= FILE_SHARE_READ;
|
||||
create_mode |= OPEN_EXISTING;
|
||||
mapping_protect |= PAGE_READONLY;
|
||||
view_access |= FILE_MAP_READ;
|
||||
break;
|
||||
case Mode::READ_WRITE:
|
||||
file_access |= GENERIC_READ | GENERIC_WRITE;
|
||||
file_share |= 0;
|
||||
create_mode |= OPEN_EXISTING;
|
||||
mapping_protect |= PAGE_READWRITE;
|
||||
view_access |= FILE_MAP_READ | FILE_MAP_WRITE;
|
||||
break;
|
||||
}
|
||||
|
||||
SYSTEM_INFO systemInfo;
|
||||
GetSystemInfo(&systemInfo);
|
||||
|
||||
const size_t aligned_offset =
|
||||
offset & (~(systemInfo.dwAllocationGranularity - 1));
|
||||
const size_t aligned_length = length + (offset - aligned_offset);
|
||||
|
||||
auto mm = std::make_unique<Win32MappedMemory>(path, mode);
|
||||
|
||||
mm->file_handle = CreateFile(path.c_str(), file_access, file_share, nullptr,
|
||||
create_mode, FILE_ATTRIBUTE_NORMAL, nullptr);
|
||||
if (!mm->file_handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mm->mapping_handle = CreateFileMapping(mm->file_handle, nullptr,
|
||||
mapping_protect, 0, 0, nullptr);
|
||||
//(DWORD)(aligned_length >> 32), (DWORD)(aligned_length & 0xFFFFFFFF), NULL);
|
||||
if (!mm->mapping_handle) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
mm->data_ = reinterpret_cast<uint8_t*>(MapViewOfFile(
|
||||
mm->mapping_handle, view_access, static_cast<DWORD>(aligned_offset >> 32),
|
||||
static_cast<DWORD>(aligned_offset & 0xFFFFFFFF), aligned_length));
|
||||
if (!mm->data_) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (length) {
|
||||
mm->size_ = aligned_length;
|
||||
} else {
|
||||
DWORD length_high;
|
||||
size_t map_length = GetFileSize(mm->file_handle, &length_high);
|
||||
map_length |= static_cast<uint64_t>(length_high) << 32;
|
||||
mm->size_ = map_length - aligned_offset;
|
||||
}
|
||||
|
||||
return std::move(mm);
|
||||
}
|
||||
|
||||
} // namespace poly
|
||||
@@ -16,6 +16,7 @@
|
||||
#include <poly/config.h>
|
||||
#include <poly/cxx_compat.h>
|
||||
#include <poly/debugging.h>
|
||||
#include <poly/mapped_memory.h>
|
||||
#include <poly/math.h>
|
||||
#include <poly/memory.h>
|
||||
#include <poly/platform.h>
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
'config.h',
|
||||
'cxx_compat.h',
|
||||
'main.h',
|
||||
'mapped_memory.h',
|
||||
'math.cc',
|
||||
'math.h',
|
||||
'memory.cc',
|
||||
@@ -23,6 +24,7 @@
|
||||
['OS == "mac" or OS == "linux"', {
|
||||
'sources': [
|
||||
'main_posix.cc',
|
||||
'mapped_memory_posix.cc',
|
||||
],
|
||||
}],
|
||||
['OS == "linux"', {
|
||||
@@ -40,6 +42,7 @@
|
||||
'sources': [
|
||||
'debugging_win.cc',
|
||||
'main_win.cc',
|
||||
'mapped_memory_win.cc',
|
||||
'threading_win.cc',
|
||||
],
|
||||
}],
|
||||
|
||||
Reference in New Issue
Block a user