Screw convention; moving include files alongside source files.

They now will show up in xcode/etc.
This commit is contained in:
Ben Vanik
2013-02-06 02:19:50 -08:00
parent 3dfd9c4b00
commit 88431eadce
151 changed files with 290 additions and 200 deletions

85
src/xenia/core/file.cc Normal file
View 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
View 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
View 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
View 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
View 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_

View 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
View 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
View 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_

View 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;
}

View 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
View 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
View 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
View 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
View 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_

View 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',
],
}],
],
}