Removing xe_mutex_t.
This commit is contained in:
parent
96fb484dd9
commit
bca49bed4b
|
@ -23,7 +23,6 @@ using namespace xe::cpu;
|
||||||
AudioSystem::AudioSystem(Emulator* emulator) :
|
AudioSystem::AudioSystem(Emulator* emulator) :
|
||||||
emulator_(emulator), memory_(emulator->memory()),
|
emulator_(emulator), memory_(emulator->memory()),
|
||||||
thread_(0), running_(false) {
|
thread_(0), running_(false) {
|
||||||
lock_ = xe_mutex_alloc();
|
|
||||||
memset(clients_, 0, sizeof(clients_));
|
memset(clients_, 0, sizeof(clients_));
|
||||||
for (size_t i = 0; i < maximum_client_count_; ++i) {
|
for (size_t i = 0; i < maximum_client_count_; ++i) {
|
||||||
client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
client_wait_handles_[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
|
@ -35,7 +34,6 @@ AudioSystem::~AudioSystem() {
|
||||||
for (size_t i = 0; i < maximum_client_count_; ++i) {
|
for (size_t i = 0; i < maximum_client_count_; ++i) {
|
||||||
CloseHandle(client_wait_handles_[i]);
|
CloseHandle(client_wait_handles_[i]);
|
||||||
}
|
}
|
||||||
xe_mutex_free(lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS AudioSystem::Setup() {
|
X_STATUS AudioSystem::Setup() {
|
||||||
|
@ -90,10 +88,10 @@ void AudioSystem::ThreadStart() {
|
||||||
if (result >= WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + (maximum_client_count_ - 1)) {
|
if (result >= WAIT_OBJECT_0 && result <= WAIT_OBJECT_0 + (maximum_client_count_ - 1)) {
|
||||||
size_t index = result - WAIT_OBJECT_0;
|
size_t index = result - WAIT_OBJECT_0;
|
||||||
do {
|
do {
|
||||||
xe_mutex_lock(lock_);
|
lock_.lock();
|
||||||
uint32_t client_callback = clients_[index].callback;
|
uint32_t client_callback = clients_[index].callback;
|
||||||
uint32_t client_callback_arg = clients_[index].wrapped_callback_arg;
|
uint32_t client_callback_arg = clients_[index].wrapped_callback_arg;
|
||||||
xe_mutex_unlock(lock_);
|
lock_.unlock();
|
||||||
if (client_callback) {
|
if (client_callback) {
|
||||||
uint64_t args[] = { client_callback_arg };
|
uint64_t args[] = { client_callback_arg };
|
||||||
processor->Execute(thread_state_, client_callback, args, XECOUNT(args));
|
processor->Execute(thread_state_, client_callback, args, XECOUNT(args));
|
||||||
|
@ -132,7 +130,7 @@ void AudioSystem::Shutdown() {
|
||||||
X_STATUS AudioSystem::RegisterClient(
|
X_STATUS AudioSystem::RegisterClient(
|
||||||
uint32_t callback, uint32_t callback_arg, size_t* out_index) {
|
uint32_t callback, uint32_t callback_arg, size_t* out_index) {
|
||||||
assert_true(unused_clients_.size());
|
assert_true(unused_clients_.size());
|
||||||
xe_mutex_lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
|
|
||||||
auto index = unused_clients_.front();
|
auto index = unused_clients_.front();
|
||||||
|
|
||||||
|
@ -157,30 +155,27 @@ X_STATUS AudioSystem::RegisterClient(
|
||||||
*out_index = index;
|
*out_index = index;
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
return X_STATUS_SUCCESS;
|
return X_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) {
|
void AudioSystem::SubmitFrame(size_t index, uint32_t samples_ptr) {
|
||||||
SCOPE_profile_cpu_f("apu");
|
SCOPE_profile_cpu_f("apu");
|
||||||
|
|
||||||
xe_mutex_lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
assert_true(index < maximum_client_count_);
|
assert_true(index < maximum_client_count_);
|
||||||
assert_true(clients_[index].driver != NULL);
|
assert_true(clients_[index].driver != NULL);
|
||||||
(clients_[index].driver)->SubmitFrame(samples_ptr);
|
(clients_[index].driver)->SubmitFrame(samples_ptr);
|
||||||
ResetEvent(client_wait_handles_[index]);
|
ResetEvent(client_wait_handles_[index]);
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioSystem::UnregisterClient(size_t index) {
|
void AudioSystem::UnregisterClient(size_t index) {
|
||||||
SCOPE_profile_cpu_f("apu");
|
SCOPE_profile_cpu_f("apu");
|
||||||
|
|
||||||
xe_mutex_lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
assert_true(index < maximum_client_count_);
|
assert_true(index < maximum_client_count_);
|
||||||
DestroyDriver(clients_[index].driver);
|
DestroyDriver(clients_[index].driver);
|
||||||
clients_[index] = { 0 };
|
clients_[index] = { 0 };
|
||||||
unused_clients_.push(index);
|
unused_clients_.push(index);
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// free60 may be useful here, however it looks like it's using a different
|
// free60 may be useful here, however it looks like it's using a different
|
||||||
|
|
|
@ -10,11 +10,12 @@
|
||||||
#ifndef XENIA_APU_AUDIO_SYSTEM_H_
|
#ifndef XENIA_APU_AUDIO_SYSTEM_H_
|
||||||
#define XENIA_APU_AUDIO_SYSTEM_H_
|
#define XENIA_APU_AUDIO_SYSTEM_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
#include <xenia/xbox.h>
|
#include <xenia/xbox.h>
|
||||||
|
|
||||||
#include <queue>
|
|
||||||
|
|
||||||
XEDECLARECLASS1(xe, Emulator);
|
XEDECLARECLASS1(xe, Emulator);
|
||||||
XEDECLARECLASS2(xe, cpu, Processor);
|
XEDECLARECLASS2(xe, cpu, Processor);
|
||||||
XEDECLARECLASS2(xe, cpu, XenonThreadState);
|
XEDECLARECLASS2(xe, cpu, XenonThreadState);
|
||||||
|
@ -74,7 +75,7 @@ protected:
|
||||||
uint32_t thread_block_;
|
uint32_t thread_block_;
|
||||||
bool running_;
|
bool running_;
|
||||||
|
|
||||||
xe_mutex_t* lock_;
|
std::mutex lock_;
|
||||||
|
|
||||||
static const size_t maximum_client_count_ = 8;
|
static const size_t maximum_client_count_ = 8;
|
||||||
|
|
||||||
|
|
|
@ -19,8 +19,8 @@ namespace xe {
|
||||||
|
|
||||||
#include <xenia/core/hash.h>
|
#include <xenia/core/hash.h>
|
||||||
#include <xenia/core/mmap.h>
|
#include <xenia/core/mmap.h>
|
||||||
#include <xenia/core/mutex.h>
|
|
||||||
#include <xenia/core/pal.h>
|
#include <xenia/core/pal.h>
|
||||||
|
#include <xenia/core/path.h>
|
||||||
#include <xenia/core/ref.h>
|
#include <xenia/core/ref.h>
|
||||||
#include <xenia/core/run_loop.h>
|
#include <xenia/core/run_loop.h>
|
||||||
#include <xenia/core/socket.h>
|
#include <xenia/core/socket.h>
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* 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 = 10000);
|
|
||||||
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_
|
|
|
@ -1,60 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* 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;
|
|
||||||
}
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <xenia/core/run_loop.h>
|
#include <xenia/core/run_loop.h>
|
||||||
|
|
||||||
#include <xenia/core/mutex.h>
|
|
||||||
#include <xenia/core/thread.h>
|
#include <xenia/core/thread.h>
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,6 @@
|
||||||
'hash.cc',
|
'hash.cc',
|
||||||
'hash.h',
|
'hash.h',
|
||||||
'mmap.h',
|
'mmap.h',
|
||||||
'mutex.h',
|
|
||||||
'pal.h',
|
'pal.h',
|
||||||
'path.cc',
|
'path.cc',
|
||||||
'path.h',
|
'path.h',
|
||||||
|
@ -20,7 +19,6 @@
|
||||||
['OS == "mac" or OS == "linux"', {
|
['OS == "mac" or OS == "linux"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
'mmap_posix.cc',
|
'mmap_posix.cc',
|
||||||
'mutex_posix.cc',
|
|
||||||
'path_posix.cc',
|
'path_posix.cc',
|
||||||
'socket_posix.cc',
|
'socket_posix.cc',
|
||||||
],
|
],
|
||||||
|
@ -38,7 +36,6 @@
|
||||||
['OS == "win"', {
|
['OS == "win"', {
|
||||||
'sources': [
|
'sources': [
|
||||||
'mmap_win.cc',
|
'mmap_win.cc',
|
||||||
'mutex_win.cc',
|
|
||||||
'pal_win.cc',
|
'pal_win.cc',
|
||||||
'path_win.cc',
|
'path_win.cc',
|
||||||
'run_loop_win.cc',
|
'run_loop_win.cc',
|
||||||
|
|
|
@ -53,7 +53,7 @@ namespace {
|
||||||
Processor::Processor(Emulator* emulator) :
|
Processor::Processor(Emulator* emulator) :
|
||||||
emulator_(emulator), export_resolver_(emulator->export_resolver()),
|
emulator_(emulator), export_resolver_(emulator->export_resolver()),
|
||||||
runtime_(0), memory_(emulator->memory()),
|
runtime_(0), memory_(emulator->memory()),
|
||||||
interrupt_thread_lock_(NULL), interrupt_thread_state_(NULL),
|
interrupt_thread_state_(NULL),
|
||||||
interrupt_thread_block_(0) {
|
interrupt_thread_block_(0) {
|
||||||
InitializeIfNeeded();
|
InitializeIfNeeded();
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,6 @@ Processor::~Processor() {
|
||||||
if (interrupt_thread_block_) {
|
if (interrupt_thread_block_) {
|
||||||
memory_->HeapFree(interrupt_thread_block_, 2048);
|
memory_->HeapFree(interrupt_thread_block_, 2048);
|
||||||
delete interrupt_thread_state_;
|
delete interrupt_thread_state_;
|
||||||
xe_mutex_free(interrupt_thread_lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
delete runtime_;
|
delete runtime_;
|
||||||
|
@ -103,7 +102,6 @@ int Processor::Setup() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt_thread_lock_ = xe_mutex_alloc(10000);
|
|
||||||
interrupt_thread_state_ = new XenonThreadState(
|
interrupt_thread_state_ = new XenonThreadState(
|
||||||
runtime_, 0, 16 * 1024, 0);
|
runtime_, 0, 16 * 1024, 0);
|
||||||
interrupt_thread_state_->set_name("Interrupt");
|
interrupt_thread_state_->set_name("Interrupt");
|
||||||
|
@ -171,7 +169,7 @@ uint64_t Processor::ExecuteInterrupt(
|
||||||
SCOPE_profile_cpu_f("cpu");
|
SCOPE_profile_cpu_f("cpu");
|
||||||
|
|
||||||
// Acquire lock on interrupt thread (we can only dispatch one at a time).
|
// Acquire lock on interrupt thread (we can only dispatch one at a time).
|
||||||
xe_mutex_lock(interrupt_thread_lock_);
|
std::lock_guard<std::mutex> lock(interrupt_thread_lock_);
|
||||||
|
|
||||||
// Set 0x10C(r13) to the current CPU ID.
|
// Set 0x10C(r13) to the current CPU ID.
|
||||||
uint8_t* p = memory_->membase();
|
uint8_t* p = memory_->membase();
|
||||||
|
@ -180,6 +178,5 @@ uint64_t Processor::ExecuteInterrupt(
|
||||||
// Execute interrupt.
|
// Execute interrupt.
|
||||||
uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count);
|
uint64_t result = Execute(interrupt_thread_state_, address, args, arg_count);
|
||||||
|
|
||||||
xe_mutex_unlock(interrupt_thread_lock_);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,11 @@
|
||||||
#ifndef XENIA_CPU_PROCESSOR_H_
|
#ifndef XENIA_CPU_PROCESSOR_H_
|
||||||
#define XENIA_CPU_PROCESSOR_H_
|
#define XENIA_CPU_PROCESSOR_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
XEDECLARECLASS2(alloy, runtime, Breakpoint);
|
XEDECLARECLASS2(alloy, runtime, Breakpoint);
|
||||||
XEDECLARECLASS1(xe, Emulator);
|
XEDECLARECLASS1(xe, Emulator);
|
||||||
|
@ -66,7 +68,7 @@ private:
|
||||||
Memory* memory_;
|
Memory* memory_;
|
||||||
|
|
||||||
Irql irql_;
|
Irql irql_;
|
||||||
xe_mutex_t* interrupt_thread_lock_;
|
std::mutex interrupt_thread_lock_;
|
||||||
XenonThreadState* interrupt_thread_state_;
|
XenonThreadState* interrupt_thread_state_;
|
||||||
uint64_t interrupt_thread_block_;
|
uint64_t interrupt_thread_block_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -19,21 +19,19 @@ namespace kernel {
|
||||||
|
|
||||||
Dispatcher::Dispatcher(KernelState* kernel_state) :
|
Dispatcher::Dispatcher(KernelState* kernel_state) :
|
||||||
kernel_state_(kernel_state) {
|
kernel_state_(kernel_state) {
|
||||||
lock_ = xe_mutex_alloc();
|
|
||||||
dpc_list_ = new NativeList(kernel_state->memory());
|
dpc_list_ = new NativeList(kernel_state->memory());
|
||||||
}
|
}
|
||||||
|
|
||||||
Dispatcher::~Dispatcher() {
|
Dispatcher::~Dispatcher() {
|
||||||
delete dpc_list_;
|
delete dpc_list_;
|
||||||
xe_mutex_free(lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dispatcher::Lock() {
|
void Dispatcher::Lock() {
|
||||||
xe_mutex_lock(lock_);
|
lock_.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Dispatcher::Unlock() {
|
void Dispatcher::Unlock() {
|
||||||
xe_mutex_unlock(lock_);
|
lock_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace kernel
|
} // namespace kernel
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
#ifndef XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
||||||
#define XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
#define XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ private:
|
||||||
private:
|
private:
|
||||||
KernelState* kernel_state_;
|
KernelState* kernel_state_;
|
||||||
|
|
||||||
xe_mutex_t* lock_;
|
std::mutex lock_;
|
||||||
NativeList* dpc_list_;
|
NativeList* dpc_list_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -9,8 +9,8 @@
|
||||||
|
|
||||||
#include <xenia/kernel/fs/devices/host_path_device.h>
|
#include <xenia/kernel/fs/devices/host_path_device.h>
|
||||||
|
|
||||||
|
#include <xenia/core/path.h>
|
||||||
#include <xenia/kernel/fs/devices/host_path_entry.h>
|
#include <xenia/kernel/fs/devices/host_path_entry.h>
|
||||||
|
|
||||||
#include <xenia/kernel/objects/xfile.h>
|
#include <xenia/kernel/objects/xfile.h>
|
||||||
|
|
||||||
using namespace xe;
|
using namespace xe;
|
||||||
|
|
|
@ -45,7 +45,6 @@ KernelState::KernelState(Emulator* emulator) :
|
||||||
user_profile_ = std::make_unique<UserProfile>();
|
user_profile_ = std::make_unique<UserProfile>();
|
||||||
|
|
||||||
object_table_ = new ObjectTable();
|
object_table_ = new ObjectTable();
|
||||||
object_mutex_ = xe_mutex_alloc(10000);
|
|
||||||
|
|
||||||
assert_null(shared_kernel_state_);
|
assert_null(shared_kernel_state_);
|
||||||
shared_kernel_state_ = this;
|
shared_kernel_state_ = this;
|
||||||
|
@ -57,7 +56,6 @@ KernelState::~KernelState() {
|
||||||
SetExecutableModule(NULL);
|
SetExecutableModule(NULL);
|
||||||
|
|
||||||
// Delete all objects.
|
// Delete all objects.
|
||||||
xe_mutex_free(object_mutex_);
|
|
||||||
delete object_table_;
|
delete object_table_;
|
||||||
|
|
||||||
// Shutdown apps.
|
// Shutdown apps.
|
||||||
|
@ -124,41 +122,37 @@ void KernelState::SetExecutableModule(XUserModule* module) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::RegisterThread(XThread* thread) {
|
void KernelState::RegisterThread(XThread* thread) {
|
||||||
xe_mutex_lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
threads_by_id_[thread->thread_id()] = thread;
|
threads_by_id_[thread->thread_id()] = thread;
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::UnregisterThread(XThread* thread) {
|
void KernelState::UnregisterThread(XThread* thread) {
|
||||||
xe_mutex_lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
auto it = threads_by_id_.find(thread->thread_id());
|
auto it = threads_by_id_.find(thread->thread_id());
|
||||||
if (it != threads_by_id_.end()) {
|
if (it != threads_by_id_.end()) {
|
||||||
threads_by_id_.erase(it);
|
threads_by_id_.erase(it);
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
||||||
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
XThread* thread = NULL;
|
XThread* thread = NULL;
|
||||||
xe_mutex_lock(object_mutex_);
|
|
||||||
auto it = threads_by_id_.find(thread_id);
|
auto it = threads_by_id_.find(thread_id);
|
||||||
if (it != threads_by_id_.end()) {
|
if (it != threads_by_id_.end()) {
|
||||||
thread = it->second;
|
thread = it->second;
|
||||||
// Caller must release.
|
// Caller must release.
|
||||||
thread->Retain();
|
thread->Retain();
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
return thread;
|
return thread;
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
||||||
xe_mutex_lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
notify_listeners_.push_back(listener);
|
notify_listeners_.push_back(listener);
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
||||||
xe_mutex_lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
for (auto it = notify_listeners_.begin(); it != notify_listeners_.end();
|
for (auto it = notify_listeners_.begin(); it != notify_listeners_.end();
|
||||||
++it) {
|
++it) {
|
||||||
if (*it == listener) {
|
if (*it == listener) {
|
||||||
|
@ -166,16 +160,14 @@ void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
|
void KernelState::BroadcastNotification(XNotificationID id, uint32_t data) {
|
||||||
xe_mutex_lock(object_mutex_);
|
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||||
for (auto it = notify_listeners_.begin(); it != notify_listeners_.end();
|
for (auto it = notify_listeners_.begin(); it != notify_listeners_.end();
|
||||||
++it) {
|
++it) {
|
||||||
(*it)->EnqueueNotification(id, data);
|
(*it)->EnqueueNotification(id, data);
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(object_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) {
|
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) {
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define XENIA_KERNEL_KERNEL_STATE_H_
|
#define XENIA_KERNEL_KERNEL_STATE_H_
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
@ -55,6 +56,7 @@ public:
|
||||||
UserProfile* user_profile() const { return user_profile_.get(); }
|
UserProfile* user_profile() const { return user_profile_.get(); }
|
||||||
|
|
||||||
ObjectTable* object_table() const { return object_table_; }
|
ObjectTable* object_table() const { return object_table_; }
|
||||||
|
std::mutex& object_mutex() { return object_mutex_; }
|
||||||
|
|
||||||
void RegisterModule(XModule* module);
|
void RegisterModule(XModule* module);
|
||||||
void UnregisterModule(XModule* module);
|
void UnregisterModule(XModule* module);
|
||||||
|
@ -85,7 +87,7 @@ private:
|
||||||
std::unique_ptr<UserProfile> user_profile_;
|
std::unique_ptr<UserProfile> user_profile_;
|
||||||
|
|
||||||
ObjectTable* object_table_;
|
ObjectTable* object_table_;
|
||||||
xe_mutex_t* object_mutex_;
|
std::mutex object_mutex_;
|
||||||
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
||||||
std::vector<XNotifyListener*> notify_listeners_;
|
std::vector<XNotifyListener*> notify_listeners_;
|
||||||
|
|
||||||
|
|
|
@ -21,12 +21,10 @@ ObjectTable::ObjectTable() :
|
||||||
table_capacity_(0),
|
table_capacity_(0),
|
||||||
table_(NULL),
|
table_(NULL),
|
||||||
last_free_entry_(0) {
|
last_free_entry_(0) {
|
||||||
table_mutex_ = xe_mutex_alloc(0);
|
|
||||||
assert_not_null(table_mutex_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ObjectTable::~ObjectTable() {
|
ObjectTable::~ObjectTable() {
|
||||||
xe_mutex_lock(table_mutex_);
|
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Release all objects.
|
// Release all objects.
|
||||||
for (uint32_t n = 0; n < table_capacity_; n++) {
|
for (uint32_t n = 0; n < table_capacity_; n++) {
|
||||||
|
@ -41,11 +39,6 @@ ObjectTable::~ObjectTable() {
|
||||||
last_free_entry_ = 0;
|
last_free_entry_ = 0;
|
||||||
xe_free(table_);
|
xe_free(table_);
|
||||||
table_ = NULL;
|
table_ = NULL;
|
||||||
|
|
||||||
xe_mutex_unlock(table_mutex_);
|
|
||||||
|
|
||||||
xe_mutex_free(table_mutex_);
|
|
||||||
table_mutex_ = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
||||||
|
@ -92,10 +85,11 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||||
|
|
||||||
X_STATUS result = X_STATUS_SUCCESS;
|
X_STATUS result = X_STATUS_SUCCESS;
|
||||||
|
|
||||||
xe_mutex_lock(table_mutex_);
|
uint32_t slot = 0;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Find a free slot.
|
// Find a free slot.
|
||||||
uint32_t slot = 0;
|
|
||||||
result = FindFreeSlot(&slot);
|
result = FindFreeSlot(&slot);
|
||||||
|
|
||||||
// Stash.
|
// Stash.
|
||||||
|
@ -107,8 +101,7 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||||
object->RetainHandle();
|
object->RetainHandle();
|
||||||
object->Retain();
|
object->Retain();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
xe_mutex_unlock(table_mutex_);
|
|
||||||
|
|
||||||
if (XSUCCEEDED(result)) {
|
if (XSUCCEEDED(result)) {
|
||||||
*out_handle = slot << 2;
|
*out_handle = slot << 2;
|
||||||
|
@ -125,13 +118,14 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
||||||
return X_STATUS_INVALID_HANDLE;
|
return X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_lock(table_mutex_);
|
XObject* object = NULL;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
uint32_t slot = handle >> 2;
|
uint32_t slot = handle >> 2;
|
||||||
|
|
||||||
// Verify slot.
|
// Verify slot.
|
||||||
XObject* object = NULL;
|
|
||||||
if (slot > table_capacity_) {
|
if (slot > table_capacity_) {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
result = X_STATUS_INVALID_HANDLE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -143,8 +137,7 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
result = X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
xe_mutex_unlock(table_mutex_);
|
|
||||||
|
|
||||||
if (object) {
|
if (object) {
|
||||||
// Release the object handle now that it is out of the table.
|
// Release the object handle now that it is out of the table.
|
||||||
|
@ -165,13 +158,14 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
||||||
return X_STATUS_INVALID_HANDLE;
|
return X_STATUS_INVALID_HANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_lock(table_mutex_);
|
XObject* object = NULL;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||||
|
|
||||||
// Lower 2 bits are ignored.
|
// Lower 2 bits are ignored.
|
||||||
uint32_t slot = handle >> 2;
|
uint32_t slot = handle >> 2;
|
||||||
|
|
||||||
// Verify slot.
|
// Verify slot.
|
||||||
XObject* object = NULL;
|
|
||||||
if (slot > table_capacity_) {
|
if (slot > table_capacity_) {
|
||||||
result = X_STATUS_INVALID_HANDLE;
|
result = X_STATUS_INVALID_HANDLE;
|
||||||
} else {
|
} else {
|
||||||
|
@ -188,7 +182,7 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
||||||
object->Retain();
|
object->Retain();
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_unlock(table_mutex_);
|
}
|
||||||
|
|
||||||
*out_object = object;
|
*out_object = object;
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -10,6 +10,8 @@
|
||||||
#ifndef XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
#ifndef XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
||||||
#define XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
#define XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/common.h>
|
#include <xenia/common.h>
|
||||||
#include <xenia/core.h>
|
#include <xenia/core.h>
|
||||||
|
|
||||||
|
@ -40,7 +42,7 @@ private:
|
||||||
XObject* object;
|
XObject* object;
|
||||||
} ObjectTableEntry;
|
} ObjectTableEntry;
|
||||||
|
|
||||||
xe_mutex_t* table_mutex_;
|
std::mutex table_mutex_;
|
||||||
uint32_t table_capacity_;
|
uint32_t table_capacity_;
|
||||||
ObjectTableEntry* table_;
|
ObjectTableEntry* table_;
|
||||||
uint32_t last_free_entry_;
|
uint32_t last_free_entry_;
|
||||||
|
|
|
@ -16,12 +16,11 @@ using namespace xe::kernel;
|
||||||
|
|
||||||
XNotifyListener::XNotifyListener(KernelState* kernel_state) :
|
XNotifyListener::XNotifyListener(KernelState* kernel_state) :
|
||||||
XObject(kernel_state, kTypeNotifyListener),
|
XObject(kernel_state, kTypeNotifyListener),
|
||||||
wait_handle_(NULL), lock_(0), mask_(0), notification_count_(0) {
|
wait_handle_(NULL), mask_(0), notification_count_(0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
XNotifyListener::~XNotifyListener() {
|
XNotifyListener::~XNotifyListener() {
|
||||||
kernel_state_->UnregisterNotifyListener(this);
|
kernel_state_->UnregisterNotifyListener(this);
|
||||||
xe_mutex_free(lock_);
|
|
||||||
if (wait_handle_) {
|
if (wait_handle_) {
|
||||||
CloseHandle(wait_handle_);
|
CloseHandle(wait_handle_);
|
||||||
}
|
}
|
||||||
|
@ -30,7 +29,6 @@ XNotifyListener::~XNotifyListener() {
|
||||||
void XNotifyListener::Initialize(uint64_t mask) {
|
void XNotifyListener::Initialize(uint64_t mask) {
|
||||||
assert_null(wait_handle_);
|
assert_null(wait_handle_);
|
||||||
|
|
||||||
lock_ = xe_mutex_alloc();
|
|
||||||
wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL);
|
wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||||
mask_ = mask;
|
mask_ = mask;
|
||||||
|
|
||||||
|
@ -43,7 +41,7 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
xe_mutex_lock(lock_);
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
if (notifications_.count(id)) {
|
if (notifications_.count(id)) {
|
||||||
// Already exists. Overwrite.
|
// Already exists. Overwrite.
|
||||||
notifications_[id] = data;
|
notifications_[id] = data;
|
||||||
|
@ -53,13 +51,12 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
||||||
notifications_.insert({ id, data });
|
notifications_.insert({ id, data });
|
||||||
}
|
}
|
||||||
SetEvent(wait_handle_);
|
SetEvent(wait_handle_);
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XNotifyListener::DequeueNotification(
|
bool XNotifyListener::DequeueNotification(
|
||||||
XNotificationID* out_id, uint32_t* out_data) {
|
XNotificationID* out_id, uint32_t* out_data) {
|
||||||
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
bool dequeued = false;
|
bool dequeued = false;
|
||||||
xe_mutex_lock(lock_);
|
|
||||||
if (notification_count_) {
|
if (notification_count_) {
|
||||||
dequeued = true;
|
dequeued = true;
|
||||||
auto it = notifications_.begin();
|
auto it = notifications_.begin();
|
||||||
|
@ -71,14 +68,13 @@ bool XNotifyListener::DequeueNotification(
|
||||||
ResetEvent(wait_handle_);
|
ResetEvent(wait_handle_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
return dequeued;
|
return dequeued;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool XNotifyListener::DequeueNotification(
|
bool XNotifyListener::DequeueNotification(
|
||||||
XNotificationID id, uint32_t* out_data) {
|
XNotificationID id, uint32_t* out_data) {
|
||||||
|
std::lock_guard<std::mutex> lock(lock_);
|
||||||
bool dequeued = false;
|
bool dequeued = false;
|
||||||
xe_mutex_lock(lock_);
|
|
||||||
if (notification_count_) {
|
if (notification_count_) {
|
||||||
dequeued = true;
|
dequeued = true;
|
||||||
auto it = notifications_.find(id);
|
auto it = notifications_.find(id);
|
||||||
|
@ -91,6 +87,5 @@ bool XNotifyListener::DequeueNotification(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
xe_mutex_unlock(lock_);
|
|
||||||
return dequeued;
|
return dequeued;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@
|
||||||
#ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
#ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||||
#define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
#define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||||
|
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/kernel/xobject.h>
|
#include <xenia/kernel/xobject.h>
|
||||||
|
|
||||||
#include <xenia/xbox.h>
|
#include <xenia/xbox.h>
|
||||||
|
@ -37,7 +39,7 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
HANDLE wait_handle_;
|
HANDLE wait_handle_;
|
||||||
xe_mutex_t* lock_;
|
std::mutex lock_;
|
||||||
std::unordered_map<XNotificationID, uint32_t> notifications_;
|
std::unordered_map<XNotificationID, uint32_t> notifications_;
|
||||||
size_t notification_count_;
|
size_t notification_count_;
|
||||||
uint64_t mask_;
|
uint64_t mask_;
|
||||||
|
|
|
@ -26,7 +26,7 @@ using namespace xe::kernel;
|
||||||
namespace {
|
namespace {
|
||||||
static uint32_t next_xthread_id = 0;
|
static uint32_t next_xthread_id = 0;
|
||||||
static thread_local XThread* current_thread_tls;
|
static thread_local XThread* current_thread_tls;
|
||||||
static xe_mutex_t* critical_region_ = xe_mutex_alloc(10000);
|
static std::mutex critical_region_;
|
||||||
static XThread* shared_kernel_thread_ = 0;
|
static XThread* shared_kernel_thread_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,7 +58,6 @@ XThread::XThread(KernelState* kernel_state,
|
||||||
creation_params_.stack_size = 16 * 1024;
|
creation_params_.stack_size = 16 * 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
apc_lock_ = xe_mutex_alloc();
|
|
||||||
apc_list_ = new NativeList(kernel_state->memory());
|
apc_list_ = new NativeList(kernel_state->memory());
|
||||||
|
|
||||||
event_ = new XEvent(kernel_state);
|
event_ = new XEvent(kernel_state);
|
||||||
|
@ -79,7 +78,6 @@ XThread::~XThread() {
|
||||||
kernel_state_->UnregisterThread(this);
|
kernel_state_->UnregisterThread(this);
|
||||||
|
|
||||||
delete apc_list_;
|
delete apc_list_;
|
||||||
xe_mutex_free(apc_lock_);
|
|
||||||
|
|
||||||
event_->Release();
|
event_->Release();
|
||||||
|
|
||||||
|
@ -421,11 +419,11 @@ void XThread::Execute() {
|
||||||
|
|
||||||
void XThread::EnterCriticalRegion() {
|
void XThread::EnterCriticalRegion() {
|
||||||
// Global critical region. This isn't right, but is easy.
|
// Global critical region. This isn't right, but is easy.
|
||||||
xe_mutex_lock(critical_region_);
|
critical_region_.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XThread::LeaveCriticalRegion() {
|
void XThread::LeaveCriticalRegion() {
|
||||||
xe_mutex_unlock(critical_region_);
|
critical_region_.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
|
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
|
||||||
|
@ -437,12 +435,12 @@ void XThread::LowerIrql(uint32_t new_irql) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void XThread::LockApc() {
|
void XThread::LockApc() {
|
||||||
xe_mutex_lock(apc_lock_);
|
apc_lock_.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void XThread::UnlockApc() {
|
void XThread::UnlockApc() {
|
||||||
bool needs_apc = apc_list_->HasPending();
|
bool needs_apc = apc_list_->HasPending();
|
||||||
xe_mutex_unlock(apc_lock_);
|
apc_lock_.unlock();
|
||||||
if (needs_apc) {
|
if (needs_apc) {
|
||||||
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs),
|
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs),
|
||||||
thread_handle_,
|
thread_handle_,
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
#define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
#define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#include <xenia/kernel/xobject.h>
|
#include <xenia/kernel/xobject.h>
|
||||||
|
|
||||||
|
@ -98,7 +99,7 @@ private:
|
||||||
char* name_;
|
char* name_;
|
||||||
|
|
||||||
std::atomic<uint32_t> irql_;
|
std::atomic<uint32_t> irql_;
|
||||||
xe_mutex_t* apc_lock_;
|
std::mutex apc_lock_;
|
||||||
NativeList* apc_list_;
|
NativeList* apc_list_;
|
||||||
|
|
||||||
XEvent* event_;
|
XEvent* event_;
|
||||||
|
|
|
@ -147,16 +147,8 @@ X_STATUS XObject::WaitMultiple(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void XObject::LockType() {
|
|
||||||
xe_mutex_lock(KernelState::shared()->object_mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XObject::UnlockType() {
|
|
||||||
xe_mutex_unlock(KernelState::shared()->object_mutex_);
|
|
||||||
}
|
|
||||||
|
|
||||||
void XObject::SetNativePointer(uint32_t native_ptr) {
|
void XObject::SetNativePointer(uint32_t native_ptr) {
|
||||||
XObject::LockType();
|
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
|
||||||
|
|
||||||
DISPATCH_HEADER* header_be =
|
DISPATCH_HEADER* header_be =
|
||||||
(DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr);
|
(DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr);
|
||||||
|
@ -173,8 +165,6 @@ void XObject::SetNativePointer(uint32_t native_ptr) {
|
||||||
object_ptr |= 0x1;
|
object_ptr |= 0x1;
|
||||||
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
||||||
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||||
|
|
||||||
XObject::UnlockType();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
|
@ -188,7 +178,7 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
// We identify this by checking the low bit of wait_list_blink - if it's 1,
|
// We identify this by checking the low bit of wait_list_blink - if it's 1,
|
||||||
// we have already put our pointer in there.
|
// we have already put our pointer in there.
|
||||||
|
|
||||||
XObject::LockType();
|
std::lock_guard<std::mutex> lock(kernel_state->object_mutex());
|
||||||
|
|
||||||
DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr;
|
DISPATCH_HEADER* header_be = (DISPATCH_HEADER*)native_ptr;
|
||||||
DISPATCH_HEADER header;
|
DISPATCH_HEADER header;
|
||||||
|
@ -208,7 +198,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
((header.wait_list_blink) & ~0x1);
|
((header.wait_list_blink) & ~0x1);
|
||||||
XObject* object = reinterpret_cast<XObject*>(object_ptr);
|
XObject* object = reinterpret_cast<XObject*>(object_ptr);
|
||||||
// TODO(benvanik): assert nothing has been changed in the struct.
|
// TODO(benvanik): assert nothing has been changed in the struct.
|
||||||
XObject::UnlockType();
|
|
||||||
return object;
|
return object;
|
||||||
} else {
|
} else {
|
||||||
// First use, create new.
|
// First use, create new.
|
||||||
|
@ -252,7 +241,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
case 24: // ThreadedDpcObject
|
case 24: // ThreadedDpcObject
|
||||||
default:
|
default:
|
||||||
assert_always();
|
assert_always();
|
||||||
XObject::UnlockType();
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -262,7 +250,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
header_be->wait_list_flink = poly::byte_swap((uint32_t)(object_ptr >> 32));
|
||||||
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
header_be->wait_list_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||||
|
|
||||||
XObject::UnlockType();
|
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,6 @@ public:
|
||||||
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||||
uint32_t alertable, uint64_t* opt_timeout);
|
uint32_t alertable, uint64_t* opt_timeout);
|
||||||
|
|
||||||
static void LockType();
|
|
||||||
static void UnlockType();
|
|
||||||
static XObject* GetObject(KernelState* kernel_state, void* native_ptr,
|
static XObject* GetObject(KernelState* kernel_state, void* native_ptr,
|
||||||
int32_t as_type = -1);
|
int32_t as_type = -1);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue