mirror of https://github.com/PCSX2/pcsx2.git
common: port ScopedPtrMT to std::atomic
v2: s/NULL/nullptr/ v3: tentative fix for MSVC // ScopedPtrMT.h(91, 0): error C2593: 'operator ==' is ambiguous
This commit is contained in:
parent
cb776d2f50
commit
89fad4d3ad
common
|
@ -190,7 +190,7 @@ public:
|
||||||
// (I think it's unsigned int vs signed int)
|
// (I think it's unsigned int vs signed int)
|
||||||
#include <wx/filefn.h>
|
#include <wx/filefn.h>
|
||||||
#define HAVE_MODE_T
|
#define HAVE_MODE_T
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <cstring> // string.h under c++
|
#include <cstring> // string.h under c++
|
||||||
|
@ -200,6 +200,7 @@ public:
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <atomic>
|
||||||
|
|
||||||
#include "Pcsx2Defs.h"
|
#include "Pcsx2Defs.h"
|
||||||
|
|
||||||
|
|
|
@ -27,25 +27,23 @@ class ScopedPtrMT
|
||||||
{
|
{
|
||||||
DeclareNoncopyableObject(ScopedPtrMT);
|
DeclareNoncopyableObject(ScopedPtrMT);
|
||||||
|
|
||||||
typedef T* TPtr;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
volatile TPtr m_ptr;
|
std::atomic<T*> m_ptr;
|
||||||
Threading::Mutex m_mtx;
|
Threading::Mutex m_mtx;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef T element_type;
|
typedef T element_type;
|
||||||
|
|
||||||
wxEXPLICIT ScopedPtrMT(T * ptr = NULL)
|
wxEXPLICIT ScopedPtrMT(T * ptr = nullptr)
|
||||||
{
|
{
|
||||||
m_ptr = ptr;
|
m_ptr = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ScopedPtrMT() throw() { _Delete_unlocked(); }
|
~ScopedPtrMT() throw() { _Delete_unlocked(); }
|
||||||
|
|
||||||
ScopedPtrMT& Reassign(T * ptr = NULL)
|
ScopedPtrMT& Reassign(T * ptr = nullptr)
|
||||||
{
|
{
|
||||||
TPtr doh = (TPtr)Threading::AtomicExchangePointer( m_ptr, ptr );
|
T* doh = m_ptr.exchange(ptr);
|
||||||
if ( ptr != doh ) delete doh;
|
if ( ptr != doh ) delete doh;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -55,19 +53,17 @@ public:
|
||||||
ScopedLock lock( m_mtx );
|
ScopedLock lock( m_mtx );
|
||||||
_Delete_unlocked();
|
_Delete_unlocked();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Removes the pointer from scoped management, but does not delete!
|
// Removes the pointer from scoped management, but does not delete!
|
||||||
// (ScopedPtr will be NULL after this method)
|
// (ScopedPtr will be nullptr after this method)
|
||||||
T *DetachPtr()
|
T *DetachPtr()
|
||||||
{
|
{
|
||||||
ScopedLock lock( m_mtx );
|
ScopedLock lock( m_mtx );
|
||||||
|
|
||||||
T *ptr = m_ptr;
|
return m_ptr.exchange(nullptr);
|
||||||
m_ptr = NULL;
|
|
||||||
return ptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the managed pointer. Can return NULL as a valid result if the ScopedPtrMT
|
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
|
||||||
// has no object in management.
|
// has no object in management.
|
||||||
T* GetPtr() const
|
T* GetPtr() const
|
||||||
{
|
{
|
||||||
|
@ -77,6 +73,7 @@ public:
|
||||||
void SwapPtr(ScopedPtrMT& other)
|
void SwapPtr(ScopedPtrMT& other)
|
||||||
{
|
{
|
||||||
ScopedLock lock( m_mtx );
|
ScopedLock lock( m_mtx );
|
||||||
|
m_ptr.exchange(other.m_ptr.exchange(m_ptr.load()));
|
||||||
T * const tmp = other.m_ptr;
|
T * const tmp = other.m_ptr;
|
||||||
other.m_ptr = m_ptr;
|
other.m_ptr = m_ptr;
|
||||||
m_ptr = tmp;
|
m_ptr = tmp;
|
||||||
|
@ -91,7 +88,7 @@ public:
|
||||||
|
|
||||||
bool operator!() const throw()
|
bool operator!() const throw()
|
||||||
{
|
{
|
||||||
return m_ptr == NULL;
|
return m_ptr.load() == nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Equality
|
// Equality
|
||||||
|
@ -106,7 +103,7 @@ public:
|
||||||
return !operator==(pT);
|
return !operator==(pT);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenient assignment operator. ScopedPtrMT = NULL will issue an automatic deletion
|
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
|
||||||
// of the managed pointer.
|
// of the managed pointer.
|
||||||
ScopedPtrMT& operator=( T* src )
|
ScopedPtrMT& operator=( T* src )
|
||||||
{
|
{
|
||||||
|
@ -120,16 +117,16 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dereference operator, returns a handle to the managed pointer.
|
// Dereference operator, returns a handle to the managed pointer.
|
||||||
// Generates a debug assertion if the object is NULL!
|
// Generates a debug assertion if the object is nullptr!
|
||||||
T& operator*() const
|
T& operator*() const
|
||||||
{
|
{
|
||||||
pxAssert(m_ptr != NULL);
|
pxAssert(m_ptr != nullptr);
|
||||||
return *m_ptr;
|
return *m_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
T* operator->() const
|
T* operator->() const
|
||||||
{
|
{
|
||||||
pxAssert(m_ptr != NULL);
|
pxAssert(m_ptr != nullptr);
|
||||||
return m_ptr;
|
return m_ptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -137,7 +134,6 @@ public:
|
||||||
protected:
|
protected:
|
||||||
void _Delete_unlocked() throw()
|
void _Delete_unlocked() throw()
|
||||||
{
|
{
|
||||||
delete m_ptr;
|
delete m_ptr.exchange(nullptr);
|
||||||
m_ptr = NULL;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -192,12 +192,6 @@ namespace Threading
|
||||||
extern bool AtomicBitTestAndReset( volatile u32& bitset, u8 bit );
|
extern bool AtomicBitTestAndReset( volatile u32& bitset, u8 bit );
|
||||||
extern bool AtomicBitTestAndReset( volatile s32& bitset, u8 bit );
|
extern bool AtomicBitTestAndReset( volatile s32& bitset, u8 bit );
|
||||||
|
|
||||||
extern void* _AtomicExchangePointer( volatile uptr& target, uptr value );
|
|
||||||
extern void* _AtomicCompareExchangePointer( volatile uptr& target, uptr value, uptr comparand );
|
|
||||||
|
|
||||||
#define AtomicExchangePointer( dest, src ) _AtomicExchangePointer( (uptr&)dest, (uptr)src )
|
|
||||||
#define AtomicCompareExchangePointer( dest, comp, src ) _AtomicExchangePointer( (uptr&)dest, (uptr)comp, (uptr)src )
|
|
||||||
|
|
||||||
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
|
// pthread Cond is an evil api that is not suited for Pcsx2 needs.
|
||||||
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
|
// Let's not use it. Use mutexes and semaphores instead to create waits. (Air)
|
||||||
#if 0
|
#if 0
|
||||||
|
|
|
@ -828,24 +828,6 @@ __fi s32 Threading::AtomicDecrement(volatile s32& Target) {
|
||||||
return _InterlockedExchangeAdd((volatile vol_t*)&Target, -1);
|
return _InterlockedExchangeAdd((volatile vol_t*)&Target, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
__fi void* Threading::_AtomicExchangePointer(volatile uptr& target, uptr value)
|
|
||||||
{
|
|
||||||
#ifdef _M_X86_64 // high-level atomic ops, please leave these 64 bit checks in place.
|
|
||||||
return (void*)_InterlockedExchange64((volatile s64*)&target, value);
|
|
||||||
#else
|
|
||||||
return (void*)_InterlockedExchange((volatile vol_t*)&target, value);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
__fi void* Threading::_AtomicCompareExchangePointer(volatile uptr& target, uptr value, uptr comparand)
|
|
||||||
{
|
|
||||||
#ifdef _M_X86_64 // high-level atomic ops, please leave these 64 bit checks in place.
|
|
||||||
return (void*)_InterlockedCompareExchange64((volatile s64*)&target, value, comparand);
|
|
||||||
#else
|
|
||||||
return (void*)_InterlockedCompareExchange((volatile vol_t*)&target, value, comparand);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// BaseThreadError
|
// BaseThreadError
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue