Screw convention; moving include files alongside source files.
They now will show up in xcode/etc.
This commit is contained in:
85
src/xenia/core/file.cc
Normal file
85
src/xenia/core/file.cc
Normal file
@@ -0,0 +1,85 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/file.h>
|
||||
|
||||
|
||||
typedef struct xe_file {
|
||||
xe_ref_t ref;
|
||||
|
||||
void* handle;
|
||||
} xe_file_t;
|
||||
|
||||
|
||||
#if XE_LIKE(WIN32)
|
||||
#define fseeko _fseeki64
|
||||
#define ftello _ftelli64
|
||||
#endif // WIN32
|
||||
|
||||
|
||||
xe_file_ref xe_file_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||
const xechar_t *path) {
|
||||
xe_file_ref file = (xe_file_ref)xe_calloc(sizeof(xe_file_t));
|
||||
xe_ref_init((xe_ref)file);
|
||||
|
||||
xechar_t mode_string[10];
|
||||
mode_string[0] = 0;
|
||||
if (mode & kXEFileModeRead) {
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("r")));
|
||||
}
|
||||
if (mode & kXEFileModeWrite) {
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("w")));
|
||||
}
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("b")));
|
||||
|
||||
#if XE_LIKE(WIN32)
|
||||
XEEXPECTZERO(_wfopen_s((FILE**)&file->handle, path, mode_string));
|
||||
#else
|
||||
file->handle = fopen(path, mode_string);
|
||||
XEEXPECTNOTNULL(file->handle);
|
||||
#endif // WIN32
|
||||
|
||||
return file;
|
||||
|
||||
XECLEANUP:
|
||||
xe_file_release(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_file_dealloc(xe_file_ref file) {
|
||||
FILE* handle = (FILE*)file->handle;
|
||||
fclose(handle);
|
||||
file->handle = NULL;
|
||||
}
|
||||
|
||||
xe_file_ref xe_file_retain(xe_file_ref file) {
|
||||
xe_ref_retain((xe_ref)file);
|
||||
return file;
|
||||
}
|
||||
|
||||
void xe_file_release(xe_file_ref file) {
|
||||
xe_ref_release((xe_ref)file, (xe_ref_dealloc_t)xe_file_dealloc);
|
||||
}
|
||||
|
||||
size_t xe_file_get_length(xe_file_ref file) {
|
||||
FILE* handle = (FILE*)file->handle;
|
||||
|
||||
fseeko(handle, 0, SEEK_END);
|
||||
return ftello(handle);
|
||||
}
|
||||
|
||||
size_t xe_file_read(xe_file_ref file, const size_t offset,
|
||||
uint8_t *buffer, const size_t buffer_size) {
|
||||
FILE* handle = (FILE*)file->handle;
|
||||
if (fseeko(handle, offset, SEEK_SET) != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return fread(buffer, 1, buffer_size, handle);
|
||||
}
|
||||
37
src/xenia/core/file.h
Normal file
37
src/xenia/core/file.h
Normal file
@@ -0,0 +1,37 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_FILE_H_
|
||||
#define XENIA_CORE_FILE_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core/pal.h>
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
struct xe_file;
|
||||
typedef struct xe_file* xe_file_ref;
|
||||
|
||||
|
||||
typedef enum {
|
||||
kXEFileModeRead = (1 << 0),
|
||||
kXEFileModeWrite = (1 << 1),
|
||||
} xe_file_mode;
|
||||
|
||||
|
||||
xe_file_ref xe_file_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||
const xechar_t *path);
|
||||
xe_file_ref xe_file_retain(xe_file_ref file);
|
||||
void xe_file_release(xe_file_ref file);
|
||||
size_t xe_file_get_length(xe_file_ref file);
|
||||
size_t xe_file_read(xe_file_ref file, const size_t offset,
|
||||
uint8_t *buffer, const size_t buffer_size);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_FILE_H_
|
||||
189
src/xenia/core/memory.cc
Normal file
189
src/xenia/core/memory.cc
Normal file
@@ -0,0 +1,189 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/memory.h>
|
||||
|
||||
#include <xenia/core/mutex.h>
|
||||
|
||||
#if !XE_PLATFORM(WIN32)
|
||||
#include <sys/mman.h>
|
||||
#endif // WIN32
|
||||
|
||||
#define MSPACES 1
|
||||
#define USE_LOCKS 0
|
||||
#define USE_DL_PREFIX 1
|
||||
#define HAVE_MORECORE 0
|
||||
#define HAVE_MMAP 0
|
||||
#define HAVE_MREMAP 0
|
||||
#define malloc_getpagesize 4096
|
||||
#define DEFAULT_GRANULARITY 64 * 1024
|
||||
#define DEFAULT_TRIM_THRESHOLD MAX_SIZE_T
|
||||
#include <third_party/dlmalloc/malloc.c.h>
|
||||
|
||||
|
||||
/**
|
||||
* Memory map:
|
||||
* 0x00000000 - 0x40000000 (1024mb) - virtual 4k pages
|
||||
* 0x40000000 - 0x80000000 (1024mb) - virtual 64k pages
|
||||
* 0x80000000 - 0x8C000000 ( 192mb) - xex 64k pages
|
||||
* 0x8C000000 - 0x90000000 ( 64mb) - xex 64k pages (encrypted)
|
||||
* 0x90000000 - 0xA0000000 ( 256mb) - xex 4k pages
|
||||
* 0xA0000000 - 0xC0000000 ( 512mb) - physical 64k pages
|
||||
*
|
||||
* We use the host OS to create an entire addressable range for this. That way
|
||||
* we don't have to emulate a TLB. It'd be really cool to pass through page
|
||||
* sizes or use madvice to let the OS know what to expect.
|
||||
*/
|
||||
|
||||
|
||||
struct xe_memory {
|
||||
xe_ref_t ref;
|
||||
|
||||
size_t length;
|
||||
void* ptr;
|
||||
|
||||
xe_mutex_t* heap_mutex;
|
||||
mspace heap;
|
||||
};
|
||||
|
||||
|
||||
xe_memory_ref xe_memory_create(xe_pal_ref pal, xe_memory_options_t options) {
|
||||
uint32_t offset;
|
||||
uint32_t mspace_size;
|
||||
|
||||
xe_memory_ref memory = (xe_memory_ref)xe_calloc(sizeof(xe_memory));
|
||||
xe_ref_init((xe_ref)memory);
|
||||
|
||||
memory->length = 0xC0000000;
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
memory->ptr = VirtualAlloc(0, memory->length,
|
||||
MEM_COMMIT | MEM_RESERVE,
|
||||
PAGE_READWRITE);
|
||||
#else
|
||||
memory->ptr = mmap(0, memory->length, PROT_READ | PROT_WRITE,
|
||||
MAP_PRIVATE | MAP_ANON, -1, 0);
|
||||
XEEXPECT(memory->ptr != MAP_FAILED);
|
||||
#endif // WIN32
|
||||
XEEXPECTNOTNULL(memory->ptr);
|
||||
|
||||
memory->heap_mutex = xe_mutex_alloc(0);
|
||||
XEEXPECTNOTNULL(memory->heap_mutex);
|
||||
|
||||
// Allocate the mspace for our heap.
|
||||
// We skip the first page to make writes to 0 easier to find.
|
||||
offset = 64 * 1024;
|
||||
mspace_size = 512 * 1024 * 1024 - offset;
|
||||
memory->heap = create_mspace_with_base(
|
||||
(uint8_t*)memory->ptr + offset, mspace_size, 0);
|
||||
|
||||
return memory;
|
||||
|
||||
XECLEANUP:
|
||||
xe_memory_release(memory);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_memory_dealloc(xe_memory_ref memory) {
|
||||
if (memory->heap_mutex && memory->heap) {
|
||||
xe_mutex_lock(memory->heap_mutex);
|
||||
destroy_mspace(memory->heap);
|
||||
memory->heap = NULL;
|
||||
xe_mutex_unlock(memory->heap_mutex);
|
||||
}
|
||||
if (memory->heap_mutex) {
|
||||
xe_mutex_free(memory->heap_mutex);
|
||||
memory->heap_mutex = NULL;
|
||||
}
|
||||
|
||||
#if XE_PLATFORM(WIN32)
|
||||
XEIGNORE(VirtualFree(memory->ptr, memory->length, MEM_RELEASE));
|
||||
#else
|
||||
munmap(memory->ptr, memory->length);
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
xe_memory_ref xe_memory_retain(xe_memory_ref memory) {
|
||||
xe_ref_retain((xe_ref)memory);
|
||||
return memory;
|
||||
}
|
||||
|
||||
void xe_memory_release(xe_memory_ref memory) {
|
||||
xe_ref_release((xe_ref)memory, (xe_ref_dealloc_t)xe_memory_dealloc);
|
||||
}
|
||||
|
||||
size_t xe_memory_get_length(xe_memory_ref memory) {
|
||||
return memory->length;
|
||||
}
|
||||
|
||||
uint8_t *xe_memory_addr(xe_memory_ref memory, uint32_t guest_addr) {
|
||||
return (uint8_t*)memory->ptr + guest_addr;
|
||||
}
|
||||
|
||||
uint32_t xe_memory_search_aligned(xe_memory_ref memory, uint32_t start,
|
||||
uint32_t end, const uint32_t *values,
|
||||
const size_t value_count) {
|
||||
XEASSERT(start <= end);
|
||||
const uint32_t *p = (const uint32_t*)xe_memory_addr(memory, start);
|
||||
const uint32_t *pe = (const uint32_t*)xe_memory_addr(memory, end);
|
||||
while (p != pe) {
|
||||
if (*p == values[0]) {
|
||||
const uint32_t *pc = p + 1;
|
||||
size_t matched = 1;
|
||||
for (size_t n = 1; n < value_count; n++, pc++) {
|
||||
if (*pc != values[n]) {
|
||||
break;
|
||||
}
|
||||
matched++;
|
||||
}
|
||||
if (matched == value_count) {
|
||||
return (uint32_t)((uint8_t*)p - (uint8_t*)memory->ptr);
|
||||
}
|
||||
}
|
||||
p++;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO(benvanik): reserve/commit states/large pages/etc
|
||||
|
||||
uint32_t xe_memory_heap_alloc(xe_memory_ref memory, uint32_t base_addr,
|
||||
uint32_t size, uint32_t flags) {
|
||||
if (base_addr) {
|
||||
return base_addr;
|
||||
}
|
||||
XEASSERT(base_addr == 0);
|
||||
XEASSERT(flags == 0);
|
||||
|
||||
XEIGNORE(xe_mutex_lock(memory->heap_mutex));
|
||||
uint8_t* p = (uint8_t*)mspace_malloc(memory->heap, size);
|
||||
XEIGNORE(xe_mutex_unlock(memory->heap_mutex));
|
||||
if (!p) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uint32_t)((uintptr_t)p - (uintptr_t)memory->ptr);
|
||||
}
|
||||
|
||||
uint32_t xe_memory_heap_free(xe_memory_ref memory, uint32_t addr,
|
||||
uint32_t flags) {
|
||||
XEASSERT(flags == 0);
|
||||
|
||||
uint8_t* p = (uint8_t*)memory->ptr + addr;
|
||||
size_t real_size = mspace_usable_size(p);
|
||||
if (!real_size) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
XEIGNORE(xe_mutex_lock(memory->heap_mutex));
|
||||
mspace_free(memory->heap, p);
|
||||
XEIGNORE(xe_mutex_unlock(memory->heap_mutex));
|
||||
|
||||
return (uint32_t)real_size;
|
||||
}
|
||||
46
src/xenia/core/memory.h
Normal file
46
src/xenia/core/memory.h
Normal file
@@ -0,0 +1,46 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_MEMORY_H_
|
||||
#define XENIA_CORE_MEMORY_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core/pal.h>
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int reserved;
|
||||
} xe_memory_options_t;
|
||||
|
||||
|
||||
struct xe_memory;
|
||||
typedef struct xe_memory* xe_memory_ref;
|
||||
|
||||
|
||||
xe_memory_ref xe_memory_create(xe_pal_ref pal, xe_memory_options_t options);
|
||||
xe_memory_ref xe_memory_retain(xe_memory_ref memory);
|
||||
void xe_memory_release(xe_memory_ref memory);
|
||||
|
||||
size_t xe_memory_get_length(xe_memory_ref memory);
|
||||
uint8_t *xe_memory_addr(xe_memory_ref memory, uint32_t guest_addr);
|
||||
|
||||
uint32_t xe_memory_search_aligned(xe_memory_ref memory, uint32_t start,
|
||||
uint32_t end, const uint32_t *values,
|
||||
const size_t value_count);
|
||||
|
||||
// These methods slice off memory from the virtual address space.
|
||||
// They should only be used by kernel modules that know what they are doing.
|
||||
uint32_t xe_memory_heap_alloc(xe_memory_ref memory, uint32_t base_addr,
|
||||
uint32_t size, uint32_t flags);
|
||||
uint32_t xe_memory_heap_free(xe_memory_ref memory, uint32_t addr,
|
||||
uint32_t flags);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_MEMORY_H_
|
||||
32
src/xenia/core/mmap.h
Normal file
32
src/xenia/core/mmap.h
Normal file
@@ -0,0 +1,32 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_MMAP_H_
|
||||
#define XENIA_CORE_MMAP_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core/file.h>
|
||||
#include <xenia/core/pal.h>
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
struct xe_mmap;
|
||||
typedef struct xe_mmap* xe_mmap_ref;
|
||||
|
||||
|
||||
xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||
const xechar_t *path,
|
||||
const size_t offset, const size_t length);
|
||||
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap);
|
||||
void xe_mmap_release(xe_mmap_ref mmap);
|
||||
uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap);
|
||||
size_t xe_mmap_get_length(xe_mmap_ref mmap);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_MMAP_H_
|
||||
101
src/xenia/core/mmap_posix.cc
Normal file
101
src/xenia/core/mmap_posix.cc
Normal file
@@ -0,0 +1,101 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/mmap.h>
|
||||
|
||||
#include <sys/mman.h>
|
||||
|
||||
|
||||
typedef struct xe_mmap {
|
||||
xe_ref_t ref;
|
||||
|
||||
void* file_handle;
|
||||
void* mmap_handle;
|
||||
|
||||
void* addr;
|
||||
size_t length;
|
||||
} xe_mmap_t;
|
||||
|
||||
|
||||
xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||
const xechar_t *path,
|
||||
const size_t offset, const size_t length) {
|
||||
xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t));
|
||||
xe_ref_init((xe_ref)mmap);
|
||||
|
||||
xechar_t mode_string[10];
|
||||
mode_string[0] = 0;
|
||||
if (mode & kXEFileModeRead) {
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("r")));
|
||||
}
|
||||
if (mode & kXEFileModeWrite) {
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("w")));
|
||||
}
|
||||
XEIGNORE(xestrcat(mode_string, XECOUNT(mode_string), XT("b")));
|
||||
|
||||
int prot = 0;
|
||||
if (mode & kXEFileModeRead) {
|
||||
prot |= PROT_READ;
|
||||
}
|
||||
if (mode & kXEFileModeWrite) {
|
||||
prot |= PROT_WRITE;
|
||||
}
|
||||
|
||||
FILE* file_handle = fopen(path, mode_string);
|
||||
mmap->file_handle = file_handle;
|
||||
XEEXPECTNOTNULL(mmap->file_handle);
|
||||
|
||||
size_t map_length;
|
||||
map_length = length;
|
||||
if (!length) {
|
||||
fseeko(file_handle, 0, SEEK_END);
|
||||
map_length = ftello(file_handle);
|
||||
}
|
||||
mmap->length = map_length;
|
||||
|
||||
mmap->addr = ::mmap(0, map_length, prot, MAP_SHARED, fileno(file_handle),
|
||||
offset);
|
||||
XEEXPECTNOTNULL(mmap->addr);
|
||||
|
||||
return mmap;
|
||||
|
||||
XECLEANUP:
|
||||
xe_mmap_release(mmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_mmap_dealloc(xe_mmap_ref mmap) {
|
||||
if (mmap->addr) {
|
||||
munmap(mmap->addr, mmap->length);
|
||||
mmap->addr = NULL;
|
||||
}
|
||||
|
||||
FILE* file_handle = (FILE*)mmap->file_handle;
|
||||
if (file_handle) {
|
||||
fclose(file_handle);
|
||||
mmap->file_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap) {
|
||||
xe_ref_retain((xe_ref)mmap);
|
||||
return mmap;
|
||||
}
|
||||
|
||||
void xe_mmap_release(xe_mmap_ref mmap) {
|
||||
xe_ref_release((xe_ref)mmap, (xe_ref_dealloc_t)xe_mmap_dealloc);
|
||||
}
|
||||
|
||||
uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap) {
|
||||
return (uint8_t*)mmap->addr;
|
||||
}
|
||||
|
||||
size_t xe_mmap_get_length(xe_mmap_ref mmap) {
|
||||
return mmap->length;
|
||||
}
|
||||
132
src/xenia/core/mmap_win.cc
Normal file
132
src/xenia/core/mmap_win.cc
Normal file
@@ -0,0 +1,132 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/mmap.h>
|
||||
|
||||
|
||||
typedef struct xe_mmap {
|
||||
xe_ref_t ref;
|
||||
|
||||
HANDLE file_handle;
|
||||
HANDLE mmap_handle;
|
||||
|
||||
void* addr;
|
||||
size_t length;
|
||||
} xe_mmap_t;
|
||||
|
||||
|
||||
xe_mmap_ref xe_mmap_open(xe_pal_ref pal, const xe_file_mode mode,
|
||||
const xechar_t *path,
|
||||
const size_t offset, const size_t length) {
|
||||
xe_mmap_ref mmap = (xe_mmap_ref)xe_calloc(sizeof(xe_mmap_t));
|
||||
xe_ref_init((xe_ref)mmap);
|
||||
|
||||
DWORD fileAccess = 0;
|
||||
DWORD fileShare = 0;
|
||||
DWORD createMode = 0;
|
||||
DWORD mappingProtect = 0;
|
||||
DWORD viewAccess = 0;
|
||||
switch (mode) {
|
||||
case kXEFileModeRead:
|
||||
fileAccess |= GENERIC_READ;
|
||||
fileShare |= FILE_SHARE_READ;
|
||||
createMode |= OPEN_EXISTING;
|
||||
mappingProtect |= PAGE_READONLY;
|
||||
viewAccess |= FILE_MAP_READ;
|
||||
break;
|
||||
case kXEFileModeWrite:
|
||||
fileAccess |= GENERIC_WRITE;
|
||||
fileShare |= 0;
|
||||
createMode |= OPEN_ALWAYS;
|
||||
mappingProtect |= PAGE_READWRITE;
|
||||
viewAccess |= FILE_MAP_WRITE;
|
||||
break;
|
||||
case kXEFileModeRead | kXEFileModeWrite:
|
||||
fileAccess |= GENERIC_READ | GENERIC_WRITE;
|
||||
fileShare |= 0;
|
||||
createMode |= OPEN_EXISTING;
|
||||
mappingProtect |= PAGE_READWRITE;
|
||||
viewAccess |= 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);
|
||||
|
||||
HANDLE file_handle = CreateFile(
|
||||
path, fileAccess, fileShare, NULL, createMode, FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
XEEXPECTNOTNULL(file_handle);
|
||||
|
||||
HANDLE handle = CreateFileMapping(
|
||||
file_handle, NULL, mappingProtect, 0, 0, NULL);
|
||||
//(DWORD)(aligned_length >> 32), (DWORD)(aligned_length & 0xFFFFFFFF), NULL);
|
||||
XEEXPECTNOTNULL(handle);
|
||||
|
||||
void* address = MapViewOfFile(handle, viewAccess,
|
||||
(DWORD)(aligned_offset >> 32),
|
||||
(DWORD)(aligned_offset & 0xFFFFFFFF),
|
||||
aligned_length);
|
||||
XEEXPECTNOTNULL(address);
|
||||
|
||||
mmap->file_handle = file_handle;
|
||||
mmap->mmap_handle = handle;
|
||||
mmap->addr = address;
|
||||
if (!length) {
|
||||
mmap->length = length;
|
||||
} else {
|
||||
size_t map_length = GetFileSize(file_handle, NULL);
|
||||
mmap->length = map_length;
|
||||
}
|
||||
|
||||
return mmap;
|
||||
|
||||
XECLEANUP:
|
||||
xe_mmap_release(mmap);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void xe_mmap_dealloc(xe_mmap_ref mmap) {
|
||||
if (mmap->addr) {
|
||||
UnmapViewOfFile(mmap->addr);
|
||||
mmap->addr = NULL;
|
||||
}
|
||||
|
||||
if (mmap->mmap_handle) {
|
||||
CloseHandle(mmap->mmap_handle);
|
||||
mmap->mmap_handle = NULL;
|
||||
}
|
||||
|
||||
if (mmap->file_handle) {
|
||||
CloseHandle(mmap->file_handle);
|
||||
mmap->file_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
xe_mmap_ref xe_mmap_retain(xe_mmap_ref mmap) {
|
||||
xe_ref_retain((xe_ref)mmap);
|
||||
return mmap;
|
||||
}
|
||||
|
||||
void xe_mmap_release(xe_mmap_ref mmap) {
|
||||
xe_ref_release((xe_ref)mmap, (xe_ref_dealloc_t)xe_mmap_dealloc);
|
||||
}
|
||||
|
||||
uint8_t* xe_mmap_get_addr(xe_mmap_ref mmap) {
|
||||
return mmap->addr;
|
||||
}
|
||||
|
||||
size_t xe_mmap_get_length(xe_mmap_ref mmap) {
|
||||
return mmap->length;
|
||||
}
|
||||
27
src/xenia/core/mutex.h
Normal file
27
src/xenia/core/mutex.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_MUTEX_H_
|
||||
#define XENIA_CORE_MUTEX_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef struct xe_mutex xe_mutex_t;
|
||||
|
||||
|
||||
xe_mutex_t* xe_mutex_alloc(uint32_t spin_count);
|
||||
void xe_mutex_free(xe_mutex_t* mutex);
|
||||
|
||||
int xe_mutex_lock(xe_mutex_t* mutex);
|
||||
int xe_mutex_trylock(xe_mutex_t* mutex);
|
||||
int xe_mutex_unlock(xe_mutex_t* mutex);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_MUTEX_H_
|
||||
60
src/xenia/core/mutex_posix.cc
Normal file
60
src/xenia/core/mutex_posix.cc
Normal file
@@ -0,0 +1,60 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/mutex.h>
|
||||
|
||||
|
||||
struct xe_mutex {
|
||||
pthread_mutex_t value;
|
||||
};
|
||||
|
||||
xe_mutex_t* xe_mutex_alloc(uint32_t spin_count) {
|
||||
xe_mutex_t* mutex = (xe_mutex_t*)xe_calloc(sizeof(xe_mutex_t));
|
||||
|
||||
int result = pthread_mutex_init(&mutex->value, NULL);
|
||||
switch (result) {
|
||||
case ENOMEM:
|
||||
case EINVAL:
|
||||
xe_free(mutex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void xe_mutex_free(xe_mutex_t* mutex) {
|
||||
int result = pthread_mutex_destroy(&mutex->value);
|
||||
switch (result) {
|
||||
case EBUSY:
|
||||
case EINVAL:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xe_free(mutex);
|
||||
}
|
||||
|
||||
int xe_mutex_lock(xe_mutex_t* mutex) {
|
||||
return pthread_mutex_lock(&mutex->value) == EINVAL ? 1 : 0;
|
||||
}
|
||||
|
||||
int xe_mutex_trylock(xe_mutex_t* mutex) {
|
||||
int result = pthread_mutex_trylock(&mutex->value);
|
||||
switch (result) {
|
||||
case EBUSY:
|
||||
case EINVAL:
|
||||
return 1;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
int xe_mutex_unlock(xe_mutex_t* mutex) {
|
||||
return pthread_mutex_unlock(&mutex->value) == EINVAL ? 1 : 0;
|
||||
}
|
||||
50
src/xenia/core/mutex_win.cc
Normal file
50
src/xenia/core/mutex_win.cc
Normal file
@@ -0,0 +1,50 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/mutex.h>
|
||||
|
||||
|
||||
struct xe_mutex {
|
||||
CRITICAL_SECTION value;
|
||||
};
|
||||
|
||||
xe_mutex_t* xe_mutex_alloc(uint32_t spin_count) {
|
||||
xe_mutex_t* mutex = (xe_mutex_t*)xe_calloc(sizeof(xe_mutex_t));
|
||||
|
||||
if (spin_count) {
|
||||
InitializeCriticalSectionAndSpinCount(&mutex->value, spin_count);
|
||||
} else {
|
||||
InitializeCriticalSection(&mutex->value);
|
||||
}
|
||||
|
||||
return mutex;
|
||||
}
|
||||
|
||||
void xe_mutex_free(xe_mutex_t* mutex) {
|
||||
DeleteCriticalSection(&mutex->value);
|
||||
xe_free(mutex);
|
||||
}
|
||||
|
||||
int xe_mutex_lock(xe_mutex_t* mutex) {
|
||||
EnterCriticalSection(&mutex->value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xe_mutex_trylock(xe_mutex_t* mutex) {
|
||||
if (TryEnterCriticalSection(&mutex->value) == TRUE) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
int xe_mutex_unlock(xe_mutex_t* mutex) {
|
||||
LeaveCriticalSection(&mutex->value);
|
||||
return 0;
|
||||
}
|
||||
39
src/xenia/core/pal.cc
Normal file
39
src/xenia/core/pal.cc
Normal file
@@ -0,0 +1,39 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/pal.h>
|
||||
|
||||
|
||||
typedef struct xe_pal {
|
||||
xe_ref_t ref;
|
||||
|
||||
} xe_pal_t;
|
||||
|
||||
|
||||
xe_pal_ref xe_pal_create(xe_pal_options_t options) {
|
||||
xe_pal_ref pal = (xe_pal_ref)xe_calloc(sizeof(xe_pal_t));
|
||||
xe_ref_init((xe_ref)pal);
|
||||
|
||||
//
|
||||
|
||||
return pal;
|
||||
}
|
||||
|
||||
void xe_pal_dealloc(xe_pal_ref pal) {
|
||||
//
|
||||
}
|
||||
|
||||
xe_pal_ref xe_pal_retain(xe_pal_ref pal) {
|
||||
xe_ref_retain((xe_ref)pal);
|
||||
return pal;
|
||||
}
|
||||
|
||||
void xe_pal_release(xe_pal_ref pal) {
|
||||
xe_ref_release((xe_ref)pal, (xe_ref_dealloc_t)xe_pal_dealloc);
|
||||
}
|
||||
31
src/xenia/core/pal.h
Normal file
31
src/xenia/core/pal.h
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_PAL_H_
|
||||
#define XENIA_CORE_PAL_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int reserved;
|
||||
} xe_pal_options_t;
|
||||
|
||||
|
||||
struct xe_pal;
|
||||
typedef struct xe_pal* xe_pal_ref;
|
||||
|
||||
|
||||
xe_pal_ref xe_pal_create(xe_pal_options_t options);
|
||||
xe_pal_ref xe_pal_retain(xe_pal_ref pal);
|
||||
void xe_pal_release(xe_pal_ref pal);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_PAL_H_
|
||||
31
src/xenia/core/ref.cc
Normal file
31
src/xenia/core/ref.cc
Normal file
@@ -0,0 +1,31 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#include <xenia/core/ref.h>
|
||||
|
||||
|
||||
void xe_ref_init(xe_ref_t* ref) {
|
||||
ref->count = 1;
|
||||
}
|
||||
|
||||
void xe_ref_retain(xe_ref_t* ref) {
|
||||
xe_atomic_inc_32(&ref->count);
|
||||
}
|
||||
|
||||
void xe_ref_release(xe_ref_t* ref, xe_ref_dealloc_t dealloc) {
|
||||
if (!ref) {
|
||||
return;
|
||||
}
|
||||
if (!xe_atomic_dec_32(&ref->count)) {
|
||||
if (dealloc) {
|
||||
dealloc(ref);
|
||||
}
|
||||
xe_free(ref);
|
||||
}
|
||||
}
|
||||
29
src/xenia/core/ref.h
Normal file
29
src/xenia/core/ref.h
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
******************************************************************************
|
||||
* Xenia : Xbox 360 Emulator Research Project *
|
||||
******************************************************************************
|
||||
* Copyright 2013 Ben Vanik. All rights reserved. *
|
||||
* Released under the BSD license - see LICENSE in the root for more details. *
|
||||
******************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef XENIA_CORE_REF_H_
|
||||
#define XENIA_CORE_REF_H_
|
||||
|
||||
#include <xenia/common.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
volatile int32_t count;
|
||||
} xe_ref_t;
|
||||
typedef xe_ref_t* xe_ref;
|
||||
|
||||
typedef void (*xe_ref_dealloc_t)(xe_ref);
|
||||
|
||||
|
||||
void xe_ref_init(xe_ref ref);
|
||||
void xe_ref_retain(xe_ref ref);
|
||||
void xe_ref_release(xe_ref ref, xe_ref_dealloc_t dealloc);
|
||||
|
||||
|
||||
#endif // XENIA_CORE_REF_H_
|
||||
30
src/xenia/core/sources.gypi
Normal file
30
src/xenia/core/sources.gypi
Normal file
@@ -0,0 +1,30 @@
|
||||
# Copyright 2013 Ben Vanik. All Rights Reserved.
|
||||
{
|
||||
'sources': [
|
||||
'file.cc',
|
||||
'file.h',
|
||||
'memory.cc',
|
||||
'memory.h',
|
||||
'mmap.h',
|
||||
'mutex.h',
|
||||
'pal.cc',
|
||||
'pal.h',
|
||||
'ref.cc',
|
||||
'ref.h',
|
||||
],
|
||||
|
||||
'conditions': [
|
||||
['OS == "mac" or OS == "linux"', {
|
||||
'sources': [
|
||||
'mmap_posix.cc',
|
||||
'mutex_posix.cc',
|
||||
],
|
||||
}],
|
||||
['OS == "win"', {
|
||||
'sources': [
|
||||
'mmap_win.cc',
|
||||
'mutex_win.cc',
|
||||
],
|
||||
}],
|
||||
],
|
||||
}
|
||||
Reference in New Issue
Block a user