Removing xe_mutex_t.
This commit is contained in:
@@ -19,21 +19,19 @@ namespace kernel {
|
||||
|
||||
Dispatcher::Dispatcher(KernelState* kernel_state) :
|
||||
kernel_state_(kernel_state) {
|
||||
lock_ = xe_mutex_alloc();
|
||||
dpc_list_ = new NativeList(kernel_state->memory());
|
||||
}
|
||||
|
||||
Dispatcher::~Dispatcher() {
|
||||
delete dpc_list_;
|
||||
xe_mutex_free(lock_);
|
||||
}
|
||||
|
||||
void Dispatcher::Lock() {
|
||||
xe_mutex_lock(lock_);
|
||||
lock_.lock();
|
||||
}
|
||||
|
||||
void Dispatcher::Unlock() {
|
||||
xe_mutex_unlock(lock_);
|
||||
lock_.unlock();
|
||||
}
|
||||
|
||||
} // namespace kernel
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_DISPATCHER_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
@@ -40,7 +42,7 @@ private:
|
||||
private:
|
||||
KernelState* kernel_state_;
|
||||
|
||||
xe_mutex_t* lock_;
|
||||
std::mutex lock_;
|
||||
NativeList* dpc_list_;
|
||||
};
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
|
||||
#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/objects/xfile.h>
|
||||
|
||||
using namespace xe;
|
||||
|
||||
@@ -45,7 +45,6 @@ KernelState::KernelState(Emulator* emulator) :
|
||||
user_profile_ = std::make_unique<UserProfile>();
|
||||
|
||||
object_table_ = new ObjectTable();
|
||||
object_mutex_ = xe_mutex_alloc(10000);
|
||||
|
||||
assert_null(shared_kernel_state_);
|
||||
shared_kernel_state_ = this;
|
||||
@@ -57,7 +56,6 @@ KernelState::~KernelState() {
|
||||
SetExecutableModule(NULL);
|
||||
|
||||
// Delete all objects.
|
||||
xe_mutex_free(object_mutex_);
|
||||
delete object_table_;
|
||||
|
||||
// Shutdown apps.
|
||||
@@ -124,41 +122,37 @@ void KernelState::SetExecutableModule(XUserModule* module) {
|
||||
}
|
||||
|
||||
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;
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
}
|
||||
|
||||
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());
|
||||
if (it != threads_by_id_.end()) {
|
||||
threads_by_id_.erase(it);
|
||||
}
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
}
|
||||
|
||||
XThread* KernelState::GetThreadByID(uint32_t thread_id) {
|
||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||
XThread* thread = NULL;
|
||||
xe_mutex_lock(object_mutex_);
|
||||
auto it = threads_by_id_.find(thread_id);
|
||||
if (it != threads_by_id_.end()) {
|
||||
thread = it->second;
|
||||
// Caller must release.
|
||||
thread->Retain();
|
||||
}
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
return thread;
|
||||
}
|
||||
|
||||
void KernelState::RegisterNotifyListener(XNotifyListener* listener) {
|
||||
xe_mutex_lock(object_mutex_);
|
||||
std::lock_guard<std::mutex> lock(object_mutex_);
|
||||
notify_listeners_.push_back(listener);
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
}
|
||||
|
||||
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();
|
||||
++it) {
|
||||
if (*it == listener) {
|
||||
@@ -166,16 +160,14 @@ void KernelState::UnregisterNotifyListener(XNotifyListener* listener) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
}
|
||||
|
||||
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();
|
||||
++it) {
|
||||
(*it)->EnqueueNotification(id, data);
|
||||
}
|
||||
xe_mutex_unlock(object_mutex_);
|
||||
}
|
||||
|
||||
void KernelState::CompleteOverlapped(uint32_t overlapped_ptr, X_RESULT result, uint32_t length) {
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define XENIA_KERNEL_KERNEL_STATE_H_
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
@@ -55,6 +56,7 @@ public:
|
||||
UserProfile* user_profile() const { return user_profile_.get(); }
|
||||
|
||||
ObjectTable* object_table() const { return object_table_; }
|
||||
std::mutex& object_mutex() { return object_mutex_; }
|
||||
|
||||
void RegisterModule(XModule* module);
|
||||
void UnregisterModule(XModule* module);
|
||||
@@ -85,7 +87,7 @@ private:
|
||||
std::unique_ptr<UserProfile> user_profile_;
|
||||
|
||||
ObjectTable* object_table_;
|
||||
xe_mutex_t* object_mutex_;
|
||||
std::mutex object_mutex_;
|
||||
std::unordered_map<uint32_t, XThread*> threads_by_id_;
|
||||
std::vector<XNotifyListener*> notify_listeners_;
|
||||
|
||||
|
||||
@@ -21,12 +21,10 @@ ObjectTable::ObjectTable() :
|
||||
table_capacity_(0),
|
||||
table_(NULL),
|
||||
last_free_entry_(0) {
|
||||
table_mutex_ = xe_mutex_alloc(0);
|
||||
assert_not_null(table_mutex_);
|
||||
}
|
||||
|
||||
ObjectTable::~ObjectTable() {
|
||||
xe_mutex_lock(table_mutex_);
|
||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||
|
||||
// Release all objects.
|
||||
for (uint32_t n = 0; n < table_capacity_; n++) {
|
||||
@@ -41,11 +39,6 @@ ObjectTable::~ObjectTable() {
|
||||
last_free_entry_ = 0;
|
||||
xe_free(table_);
|
||||
table_ = NULL;
|
||||
|
||||
xe_mutex_unlock(table_mutex_);
|
||||
|
||||
xe_mutex_free(table_mutex_);
|
||||
table_mutex_ = NULL;
|
||||
}
|
||||
|
||||
X_STATUS ObjectTable::FindFreeSlot(uint32_t* out_slot) {
|
||||
@@ -91,25 +84,25 @@ X_STATUS ObjectTable::AddHandle(XObject* object, X_HANDLE* out_handle) {
|
||||
assert_not_null(out_handle);
|
||||
|
||||
X_STATUS result = X_STATUS_SUCCESS;
|
||||
|
||||
xe_mutex_lock(table_mutex_);
|
||||
|
||||
// Find a free slot.
|
||||
|
||||
uint32_t slot = 0;
|
||||
result = FindFreeSlot(&slot);
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||
|
||||
// Stash.
|
||||
if (XSUCCEEDED(result)) {
|
||||
ObjectTableEntry& entry = table_[slot];
|
||||
entry.object = object;
|
||||
// Find a free slot.
|
||||
result = FindFreeSlot(&slot);
|
||||
|
||||
// Retain so long as the object is in the table.
|
||||
object->RetainHandle();
|
||||
object->Retain();
|
||||
// Stash.
|
||||
if (XSUCCEEDED(result)) {
|
||||
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)) {
|
||||
*out_handle = slot << 2;
|
||||
}
|
||||
@@ -125,27 +118,27 @@ X_STATUS ObjectTable::RemoveHandle(X_HANDLE 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;
|
||||
if (slot > table_capacity_) {
|
||||
result = X_STATUS_INVALID_HANDLE;
|
||||
} else {
|
||||
ObjectTableEntry& entry = table_[slot];
|
||||
if (entry.object) {
|
||||
// Release after we lose the lock.
|
||||
object = entry.object;
|
||||
} else {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||
|
||||
// Lower 2 bits are ignored.
|
||||
uint32_t slot = handle >> 2;
|
||||
|
||||
// Verify slot.
|
||||
if (slot > table_capacity_) {
|
||||
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) {
|
||||
// Release the object handle now that it is out of the table.
|
||||
object->ReleaseHandle();
|
||||
@@ -165,30 +158,31 @@ X_STATUS ObjectTable::GetObject(X_HANDLE handle, XObject** out_object) {
|
||||
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;
|
||||
if (slot > table_capacity_) {
|
||||
result = X_STATUS_INVALID_HANDLE;
|
||||
} else {
|
||||
ObjectTableEntry& entry = table_[slot];
|
||||
if (entry.object) {
|
||||
object = entry.object;
|
||||
} else {
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(table_mutex_);
|
||||
|
||||
// Lower 2 bits are ignored.
|
||||
uint32_t slot = handle >> 2;
|
||||
|
||||
// Verify slot.
|
||||
if (slot > table_capacity_) {
|
||||
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.
|
||||
if (object) {
|
||||
object->Retain();
|
||||
}
|
||||
// Retain the object pointer.
|
||||
if (object) {
|
||||
object->Retain();
|
||||
}
|
||||
|
||||
xe_mutex_unlock(table_mutex_);
|
||||
}
|
||||
|
||||
*out_object = object;
|
||||
return result;
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_OBJECT_TABLE_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/common.h>
|
||||
#include <xenia/core.h>
|
||||
|
||||
@@ -40,7 +42,7 @@ private:
|
||||
XObject* object;
|
||||
} ObjectTableEntry;
|
||||
|
||||
xe_mutex_t* table_mutex_;
|
||||
std::mutex table_mutex_;
|
||||
uint32_t table_capacity_;
|
||||
ObjectTableEntry* table_;
|
||||
uint32_t last_free_entry_;
|
||||
|
||||
@@ -16,12 +16,11 @@ using namespace xe::kernel;
|
||||
|
||||
XNotifyListener::XNotifyListener(KernelState* kernel_state) :
|
||||
XObject(kernel_state, kTypeNotifyListener),
|
||||
wait_handle_(NULL), lock_(0), mask_(0), notification_count_(0) {
|
||||
wait_handle_(NULL), mask_(0), notification_count_(0) {
|
||||
}
|
||||
|
||||
XNotifyListener::~XNotifyListener() {
|
||||
kernel_state_->UnregisterNotifyListener(this);
|
||||
xe_mutex_free(lock_);
|
||||
if (wait_handle_) {
|
||||
CloseHandle(wait_handle_);
|
||||
}
|
||||
@@ -30,7 +29,6 @@ XNotifyListener::~XNotifyListener() {
|
||||
void XNotifyListener::Initialize(uint64_t mask) {
|
||||
assert_null(wait_handle_);
|
||||
|
||||
lock_ = xe_mutex_alloc();
|
||||
wait_handle_ = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
mask_ = mask;
|
||||
|
||||
@@ -43,7 +41,7 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
||||
return;
|
||||
}
|
||||
|
||||
xe_mutex_lock(lock_);
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
if (notifications_.count(id)) {
|
||||
// Already exists. Overwrite.
|
||||
notifications_[id] = data;
|
||||
@@ -53,13 +51,12 @@ void XNotifyListener::EnqueueNotification(XNotificationID id, uint32_t data) {
|
||||
notifications_.insert({ id, data });
|
||||
}
|
||||
SetEvent(wait_handle_);
|
||||
xe_mutex_unlock(lock_);
|
||||
}
|
||||
|
||||
bool XNotifyListener::DequeueNotification(
|
||||
XNotificationID* out_id, uint32_t* out_data) {
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
bool dequeued = false;
|
||||
xe_mutex_lock(lock_);
|
||||
if (notification_count_) {
|
||||
dequeued = true;
|
||||
auto it = notifications_.begin();
|
||||
@@ -71,14 +68,13 @@ bool XNotifyListener::DequeueNotification(
|
||||
ResetEvent(wait_handle_);
|
||||
}
|
||||
}
|
||||
xe_mutex_unlock(lock_);
|
||||
return dequeued;
|
||||
}
|
||||
|
||||
bool XNotifyListener::DequeueNotification(
|
||||
XNotificationID id, uint32_t* out_data) {
|
||||
std::lock_guard<std::mutex> lock(lock_);
|
||||
bool dequeued = false;
|
||||
xe_mutex_lock(lock_);
|
||||
if (notification_count_) {
|
||||
dequeued = true;
|
||||
auto it = notifications_.find(id);
|
||||
@@ -91,6 +87,5 @@ bool XNotifyListener::DequeueNotification(
|
||||
}
|
||||
}
|
||||
}
|
||||
xe_mutex_unlock(lock_);
|
||||
return dequeued;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XNOTIFY_LISTENER_H_
|
||||
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
@@ -37,7 +39,7 @@ public:
|
||||
|
||||
private:
|
||||
HANDLE wait_handle_;
|
||||
xe_mutex_t* lock_;
|
||||
std::mutex lock_;
|
||||
std::unordered_map<XNotificationID, uint32_t> notifications_;
|
||||
size_t notification_count_;
|
||||
uint64_t mask_;
|
||||
|
||||
@@ -26,7 +26,7 @@ using namespace xe::kernel;
|
||||
namespace {
|
||||
static uint32_t next_xthread_id = 0;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ XThread::XThread(KernelState* kernel_state,
|
||||
creation_params_.stack_size = 16 * 1024;
|
||||
}
|
||||
|
||||
apc_lock_ = xe_mutex_alloc();
|
||||
apc_list_ = new NativeList(kernel_state->memory());
|
||||
|
||||
event_ = new XEvent(kernel_state);
|
||||
@@ -79,7 +78,6 @@ XThread::~XThread() {
|
||||
kernel_state_->UnregisterThread(this);
|
||||
|
||||
delete apc_list_;
|
||||
xe_mutex_free(apc_lock_);
|
||||
|
||||
event_->Release();
|
||||
|
||||
@@ -421,11 +419,11 @@ void XThread::Execute() {
|
||||
|
||||
void XThread::EnterCriticalRegion() {
|
||||
// Global critical region. This isn't right, but is easy.
|
||||
xe_mutex_lock(critical_region_);
|
||||
critical_region_.lock();
|
||||
}
|
||||
|
||||
void XThread::LeaveCriticalRegion() {
|
||||
xe_mutex_unlock(critical_region_);
|
||||
critical_region_.unlock();
|
||||
}
|
||||
|
||||
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
|
||||
@@ -437,12 +435,12 @@ void XThread::LowerIrql(uint32_t new_irql) {
|
||||
}
|
||||
|
||||
void XThread::LockApc() {
|
||||
xe_mutex_lock(apc_lock_);
|
||||
apc_lock_.lock();
|
||||
}
|
||||
|
||||
void XThread::UnlockApc() {
|
||||
bool needs_apc = apc_list_->HasPending();
|
||||
xe_mutex_unlock(apc_lock_);
|
||||
apc_lock_.unlock();
|
||||
if (needs_apc) {
|
||||
QueueUserAPC(reinterpret_cast<PAPCFUNC>(DeliverAPCs),
|
||||
thread_handle_,
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
@@ -98,7 +99,7 @@ private:
|
||||
char* name_;
|
||||
|
||||
std::atomic<uint32_t> irql_;
|
||||
xe_mutex_t* apc_lock_;
|
||||
std::mutex apc_lock_;
|
||||
NativeList* apc_list_;
|
||||
|
||||
XEvent* event_;
|
||||
|
||||
@@ -147,16 +147,8 @@ X_STATUS XObject::WaitMultiple(
|
||||
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) {
|
||||
XObject::LockType();
|
||||
std::lock_guard<std::mutex> lock(kernel_state_->object_mutex());
|
||||
|
||||
DISPATCH_HEADER* header_be =
|
||||
(DISPATCH_HEADER*)kernel_state_->memory()->Translate(native_ptr);
|
||||
@@ -173,8 +165,6 @@ void XObject::SetNativePointer(uint32_t native_ptr) {
|
||||
object_ptr |= 0x1;
|
||||
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));
|
||||
|
||||
XObject::UnlockType();
|
||||
}
|
||||
|
||||
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 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;
|
||||
@@ -208,7 +198,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||
((header.wait_list_blink) & ~0x1);
|
||||
XObject* object = reinterpret_cast<XObject*>(object_ptr);
|
||||
// TODO(benvanik): assert nothing has been changed in the struct.
|
||||
XObject::UnlockType();
|
||||
return object;
|
||||
} else {
|
||||
// First use, create new.
|
||||
@@ -252,7 +241,6 @@ XObject* XObject::GetObject(KernelState* kernel_state, void* native_ptr,
|
||||
case 24: // ThreadedDpcObject
|
||||
default:
|
||||
assert_always();
|
||||
XObject::UnlockType();
|
||||
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_blink = poly::byte_swap((uint32_t)(object_ptr & 0xFFFFFFFF));
|
||||
|
||||
XObject::UnlockType();
|
||||
return object;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,8 +74,6 @@ public:
|
||||
uint32_t wait_type, uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout);
|
||||
|
||||
static void LockType();
|
||||
static void UnlockType();
|
||||
static XObject* GetObject(KernelState* kernel_state, void* native_ptr,
|
||||
int32_t as_type = -1);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user