Migrating atomic ops to std::atomic where possible and poly.

This commit is contained in:
Ben Vanik
2014-07-12 17:48:54 -07:00
parent bf882714d0
commit 9b78dd977b
18 changed files with 174 additions and 139 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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