DANGER DANGER. Switching to global critical region.
This changes almost all locks held by guest threads to use a single global critical region. This emulates the behavior on the PPC of disabling interrupts (by calls like KeRaiseIrqlToDpcLevel or masking interrupts), and prevents deadlocks from occuring when threads are suspended or otherwise blocked. This has performance implications and a pass is needed to ensure the locking is as granular as possible. It could also break everything because it's fundamentally unsound. We'll see.
This commit is contained in:
@@ -9,6 +9,7 @@
|
||||
|
||||
#include "xenia/cpu/frontend/ppc_frontend.h"
|
||||
|
||||
#include "xenia/base/atomic.h"
|
||||
#include "xenia/cpu/frontend/ppc_context.h"
|
||||
#include "xenia/cpu/frontend/ppc_disasm.h"
|
||||
#include "xenia/cpu/frontend/ppc_emit.h"
|
||||
@@ -71,20 +72,20 @@ void EnterGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) {
|
||||
auto global_mutex = reinterpret_cast<xe::recursive_mutex*>(arg0);
|
||||
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
|
||||
global_mutex->lock();
|
||||
*global_lock_count = *global_lock_count + 1;
|
||||
xe::atomic_inc(global_lock_count);
|
||||
}
|
||||
|
||||
// Leaves the global lock. Safe to recursion.
|
||||
void LeaveGlobalLock(PPCContext* ppc_context, void* arg0, void* arg1) {
|
||||
auto global_mutex = reinterpret_cast<xe::recursive_mutex*>(arg0);
|
||||
auto global_lock_count = reinterpret_cast<int32_t*>(arg1);
|
||||
*global_lock_count = *global_lock_count - 1;
|
||||
assert_true(*global_lock_count >= 0);
|
||||
auto new_lock_count = xe::atomic_dec(global_lock_count);
|
||||
assert_true(new_lock_count >= 0);
|
||||
global_mutex->unlock();
|
||||
}
|
||||
|
||||
bool PPCFrontend::Initialize() {
|
||||
void* arg0 = reinterpret_cast<void*>(processor_->global_mutex());
|
||||
void* arg0 = reinterpret_cast<void*>(&xe::global_critical_region::mutex());
|
||||
void* arg1 = reinterpret_cast<void*>(&builtins_.global_lock_count);
|
||||
builtins_.check_global_lock =
|
||||
processor_->DefineBuiltin("CheckGlobalLock", CheckGlobalLock, arg0, arg1);
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
#define XENIA_CPU_FRONTEND_PPC_FRONTEND_H_
|
||||
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
#include "xenia/base/mutex.h"
|
||||
#include "xenia/base/type_pool.h"
|
||||
#include "xenia/cpu/frontend/context_info.h"
|
||||
#include "xenia/cpu/function.h"
|
||||
|
||||
Reference in New Issue
Block a user