Removing xe_mutex_t.

This commit is contained in:
Ben Vanik 2014-08-16 00:56:50 -07:00
parent 96fb484dd9
commit bca49bed4b
23 changed files with 101 additions and 276 deletions

View File

@ -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

View File

@ -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;

View File

@ -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>

View File

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

View File

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

View File

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

View File

@ -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>

View File

@ -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',

View File

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

View File

@ -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_;
}; };

View File

@ -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

View File

@ -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_;
}; };

View File

@ -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;

View File

@ -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) {

View File

@ -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_;

View File

@ -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,24 +85,24 @@ 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_);
// Find a free slot.
uint32_t slot = 0; uint32_t slot = 0;
result = FindFreeSlot(&slot); {
std::lock_guard<std::mutex> lock(table_mutex_);
// Stash. // Find a free slot.
if (XSUCCEEDED(result)) { result = FindFreeSlot(&slot);
ObjectTableEntry& entry = table_[slot];
entry.object = object;
// Retain so long as the object is in the table. // Stash.
object->RetainHandle(); if (XSUCCEEDED(result)) {
object->Retain(); ObjectTableEntry& entry = table_[slot];
entry.object = object;
// Retain so long as the object is in the table.
object->RetainHandle();
object->Retain();
}
} }
xe_mutex_unlock(table_mutex_);
if (XSUCCEEDED(result)) { if (XSUCCEEDED(result)) {
*out_handle = slot << 2; *out_handle = slot << 2;
} }
@ -125,27 +118,27 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE handle) {
return X_STATUS_INVALID_HANDLE; return X_STATUS_INVALID_HANDLE;
} }
xe_mutex_lock(table_mutex_);
// Lower 2 bits are ignored.
uint32_t slot = handle >> 2;
// Verify slot.
XObject* object = NULL; XObject* object = NULL;
if (slot > table_capacity_) { {
result = X_STATUS_INVALID_HANDLE; std::lock_guard<std::mutex> lock(table_mutex_);
} else {
ObjectTableEntry& entry = table_[slot]; // Lower 2 bits are ignored.
if (entry.object) { uint32_t slot = handle >> 2;
// Release after we lose the lock.
object = entry.object; // Verify slot.
} else { if (slot > table_capacity_) {
result = X_STATUS_INVALID_HANDLE; result = X_STATUS_INVALID_HANDLE;
} else {
ObjectTableEntry& entry = table_[slot];
if (entry.object) {
// Release after we lose the lock.
object = entry.object;
} else {
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.
object->ReleaseHandle(); object->ReleaseHandle();
@ -165,30 +158,31 @@ 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_);
// Lower 2 bits are ignored.
uint32_t slot = handle >> 2;
// Verify slot.
XObject* object = NULL; XObject* object = NULL;
if (slot > table_capacity_) { {
result = X_STATUS_INVALID_HANDLE; std::lock_guard<std::mutex> lock(table_mutex_);
} else {
ObjectTableEntry& entry = table_[slot]; // Lower 2 bits are ignored.
if (entry.object) { uint32_t slot = handle >> 2;
object = entry.object;
} else { // Verify slot.
if (slot > table_capacity_) {
result = X_STATUS_INVALID_HANDLE; result = X_STATUS_INVALID_HANDLE;
} else {
ObjectTableEntry& entry = table_[slot];
if (entry.object) {
object = entry.object;
} else {
result = X_STATUS_INVALID_HANDLE;
}
} }
}
// Retain the object pointer. // Retain the object pointer.
if (object) { if (object) {
object->Retain(); object->Retain();
} }
xe_mutex_unlock(table_mutex_); }
*out_object = object; *out_object = object;
return result; return result;

View File

@ -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_;

View File

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

View File

@ -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_;

View File

@ -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_,

View File

@ -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_;

View File

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

View File

@ -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);