Migrating atomic ops to std::atomic where possible and poly.
This commit is contained in:
@@ -406,7 +406,7 @@ void XThread::LeaveCriticalRegion() {
|
||||
}
|
||||
|
||||
uint32_t XThread::RaiseIrql(uint32_t new_irql) {
|
||||
return xe_atomic_exchange_32(new_irql, &irql_);
|
||||
return irql_.exchange(new_irql);
|
||||
}
|
||||
|
||||
void XThread::LowerIrql(uint32_t new_irql) {
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XTHREAD_H_
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <xenia/kernel/xobject.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
@@ -94,7 +96,7 @@ private:
|
||||
|
||||
char* name_;
|
||||
|
||||
uint32_t irql_;
|
||||
std::atomic<uint32_t> irql_;
|
||||
xe_mutex_t* apc_lock_;
|
||||
NativeList* apc_list_;
|
||||
|
||||
|
||||
@@ -606,13 +606,13 @@ void xeRtlEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) {
|
||||
|
||||
uint32_t spin_wait_remaining = cs->spin_count_div_256 * 256;
|
||||
spin:
|
||||
if (xe_atomic_inc_32(&cs->lock_count) != 0) {
|
||||
if (poly::atomic_inc(&cs->lock_count) != 0) {
|
||||
// If this thread already owns the CS increment the recursion count.
|
||||
if (cs->owning_thread_id == thread_id) {
|
||||
cs->recursion_count++;
|
||||
return;
|
||||
}
|
||||
xe_atomic_dec_32(&cs->lock_count);
|
||||
poly::atomic_dec(&cs->lock_count);
|
||||
|
||||
// Thread was locked - spin wait.
|
||||
if (spin_wait_remaining) {
|
||||
@@ -658,13 +658,13 @@ uint32_t xeRtlTryEnterCriticalSection(uint32_t cs_ptr, uint32_t thread_id) {
|
||||
|
||||
X_RTL_CRITICAL_SECTION* cs = (X_RTL_CRITICAL_SECTION*)IMPL_MEM_ADDR(cs_ptr);
|
||||
|
||||
if (xe_atomic_cas_32(-1, 0, &cs->lock_count)) {
|
||||
if (poly::atomic_cas(-1, 0, &cs->lock_count)) {
|
||||
// Able to steal the lock right away.
|
||||
cs->owning_thread_id = thread_id;
|
||||
cs->recursion_count = 1;
|
||||
return 1;
|
||||
} else if (cs->owning_thread_id == thread_id) {
|
||||
xe_atomic_inc_32(&cs->lock_count);
|
||||
poly::atomic_inc(&cs->lock_count);
|
||||
++cs->recursion_count;
|
||||
return 1;
|
||||
}
|
||||
@@ -699,13 +699,13 @@ void xeRtlLeaveCriticalSection(uint32_t cs_ptr) {
|
||||
// Drop recursion count - if we are still not zero'ed return.
|
||||
uint32_t recursion_count = --cs->recursion_count;
|
||||
if (recursion_count) {
|
||||
xe_atomic_dec_32(&cs->lock_count);
|
||||
poly::atomic_dec(&cs->lock_count);
|
||||
return;
|
||||
}
|
||||
|
||||
// Unlock!
|
||||
cs->owning_thread_id = 0;
|
||||
if (xe_atomic_dec_32(&cs->lock_count) != -1) {
|
||||
if (poly::atomic_dec(&cs->lock_count) != -1) {
|
||||
// There were waiters - wake one of them.
|
||||
// TODO(benvanik): wake a waiter.
|
||||
XELOGE("RtlLeaveCriticalSection would have woken a waiter");
|
||||
|
||||
@@ -1258,9 +1258,9 @@ SHIM_CALL NtSignalAndWaitForSingleObjectEx_shim(
|
||||
}
|
||||
|
||||
|
||||
uint32_t xeKfAcquireSpinLock(void* lock_ptr) {
|
||||
uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr) {
|
||||
// Lock.
|
||||
while (!xe_atomic_cas_32(0, 1, lock_ptr)) {
|
||||
while (!poly::atomic_cas(0, 1, lock_ptr)) {
|
||||
// Spin!
|
||||
// TODO(benvanik): error on deadlock?
|
||||
}
|
||||
@@ -1279,19 +1279,20 @@ SHIM_CALL KfAcquireSpinLock_shim(
|
||||
"KfAcquireSpinLock(%.8X)",
|
||||
lock_ptr);
|
||||
|
||||
uint32_t old_irql = xeKfAcquireSpinLock(SHIM_MEM_ADDR(lock_ptr));
|
||||
auto lock = reinterpret_cast<uint32_t*>(SHIM_MEM_ADDR(lock_ptr));
|
||||
uint32_t old_irql = xeKfAcquireSpinLock(lock);
|
||||
|
||||
SHIM_SET_RETURN_64(old_irql);
|
||||
}
|
||||
|
||||
|
||||
void xeKfReleaseSpinLock(void* lock_ptr, uint32_t old_irql) {
|
||||
void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql) {
|
||||
// Restore IRQL.
|
||||
XThread* thread = XThread::GetCurrentThread();
|
||||
thread->LowerIrql(old_irql);
|
||||
|
||||
// Unlock.
|
||||
xe_atomic_dec_32(lock_ptr);
|
||||
poly::atomic_dec(lock_ptr);
|
||||
}
|
||||
|
||||
|
||||
@@ -1305,7 +1306,8 @@ SHIM_CALL KfReleaseSpinLock_shim(
|
||||
lock_ptr,
|
||||
old_irql);
|
||||
|
||||
xeKfReleaseSpinLock(SHIM_MEM_ADDR(lock_ptr), old_irql);
|
||||
xeKfReleaseSpinLock(reinterpret_cast<uint32_t*>(SHIM_MEM_ADDR(lock_ptr)),
|
||||
old_irql);
|
||||
}
|
||||
|
||||
|
||||
@@ -1318,8 +1320,8 @@ SHIM_CALL KeAcquireSpinLockAtRaisedIrql_shim(
|
||||
lock_ptr);
|
||||
|
||||
// Lock.
|
||||
void* lock = SHIM_MEM_ADDR(lock_ptr);
|
||||
while (!xe_atomic_cas_32(0, 1, lock)) {
|
||||
auto lock = reinterpret_cast<uint32_t*>(SHIM_MEM_ADDR(lock_ptr));
|
||||
while (!poly::atomic_cas(0, 1, lock)) {
|
||||
// Spin!
|
||||
// TODO(benvanik): error on deadlock?
|
||||
}
|
||||
@@ -1335,8 +1337,8 @@ SHIM_CALL KeReleaseSpinLockFromRaisedIrql_shim(
|
||||
lock_ptr);
|
||||
|
||||
// Unlock.
|
||||
void* lock = SHIM_MEM_ADDR(lock_ptr);
|
||||
xe_atomic_dec_32(lock);
|
||||
auto lock = reinterpret_cast<uint32_t*>(SHIM_MEM_ADDR(lock_ptr));
|
||||
poly::atomic_dec(lock);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -52,8 +52,8 @@ X_STATUS xeKeWaitForSingleObject(
|
||||
void* object_ptr, uint32_t wait_reason, uint32_t processor_mode,
|
||||
uint32_t alertable, uint64_t* opt_timeout);
|
||||
|
||||
uint32_t xeKfAcquireSpinLock(void* lock_ptr);
|
||||
void xeKfReleaseSpinLock(void* lock_ptr, uint32_t old_irql);
|
||||
uint32_t xeKfAcquireSpinLock(uint32_t* lock_ptr);
|
||||
void xeKfReleaseSpinLock(uint32_t* lock_ptr, uint32_t old_irql);
|
||||
|
||||
void xeKeEnterCriticalRegion();
|
||||
void xeKeLeaveCriticalRegion();
|
||||
|
||||
@@ -46,22 +46,22 @@ X_HANDLE XObject::handle() const {
|
||||
}
|
||||
|
||||
void XObject::RetainHandle() {
|
||||
xe_atomic_inc_32(&handle_ref_count_);
|
||||
++handle_ref_count_;
|
||||
}
|
||||
|
||||
bool XObject::ReleaseHandle() {
|
||||
if (!xe_atomic_dec_32(&handle_ref_count_)) {
|
||||
if (--handle_ref_count_ == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void XObject::Retain() {
|
||||
xe_atomic_inc_32(&pointer_ref_count_);
|
||||
++pointer_ref_count_;
|
||||
}
|
||||
|
||||
void XObject::Release() {
|
||||
if (!xe_atomic_dec_32(&pointer_ref_count_)) {
|
||||
if (--pointer_ref_count_ == 0) {
|
||||
assert_true(pointer_ref_count_ >= handle_ref_count_);
|
||||
delete this;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
#ifndef XENIA_KERNEL_XBOXKRNL_XOBJECT_H_
|
||||
#define XENIA_KERNEL_XBOXKRNL_XOBJECT_H_
|
||||
|
||||
#include <atomic>
|
||||
|
||||
#include <xenia/kernel/kernel_state.h>
|
||||
|
||||
#include <xenia/xbox.h>
|
||||
@@ -87,8 +89,8 @@ protected:
|
||||
KernelState* kernel_state_;
|
||||
|
||||
private:
|
||||
volatile int32_t handle_ref_count_;
|
||||
volatile int32_t pointer_ref_count_;
|
||||
std::atomic<int32_t> handle_ref_count_;
|
||||
std::atomic<int32_t> pointer_ref_count_;
|
||||
|
||||
Type type_;
|
||||
X_HANDLE handle_;
|
||||
|
||||
Reference in New Issue
Block a user