From 89fad4d3ad80b6fbc68f173372db1fea52e79351 Mon Sep 17 00:00:00 2001 From: Gregory Hainaut Date: Mon, 22 Feb 2016 19:36:45 +0100 Subject: [PATCH] common: port ScopedPtrMT to std::atomic v2: s/NULL/nullptr/ v3: tentative fix for MSVC // ScopedPtrMT.h(91, 0): error C2593: 'operator ==' is ambiguous --- common/include/Utilities/Dependencies.h | 3 ++- common/include/Utilities/ScopedPtrMT.h | 34 +++++++++++-------------- common/include/Utilities/Threading.h | 6 ----- common/src/Utilities/ThreadTools.cpp | 18 ------------- 4 files changed, 17 insertions(+), 44 deletions(-) diff --git a/common/include/Utilities/Dependencies.h b/common/include/Utilities/Dependencies.h index 31bc649149..80733a2676 100644 --- a/common/include/Utilities/Dependencies.h +++ b/common/include/Utilities/Dependencies.h @@ -190,7 +190,7 @@ public: // (I think it's unsigned int vs signed int) #include #define HAVE_MODE_T -#endif +#endif #include #include // string.h under c++ @@ -200,6 +200,7 @@ public: #include #include #include +#include #include "Pcsx2Defs.h" diff --git a/common/include/Utilities/ScopedPtrMT.h b/common/include/Utilities/ScopedPtrMT.h index d8dab7edbc..9c5c0dc1db 100644 --- a/common/include/Utilities/ScopedPtrMT.h +++ b/common/include/Utilities/ScopedPtrMT.h @@ -27,25 +27,23 @@ class ScopedPtrMT { DeclareNoncopyableObject(ScopedPtrMT); - typedef T* TPtr; - protected: - volatile TPtr m_ptr; + std::atomic m_ptr; Threading::Mutex m_mtx; public: typedef T element_type; - wxEXPLICIT ScopedPtrMT(T * ptr = NULL) + wxEXPLICIT ScopedPtrMT(T * ptr = nullptr) { m_ptr = ptr; } ~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; return *this; } @@ -55,19 +53,17 @@ public: ScopedLock lock( m_mtx ); _Delete_unlocked(); } - + // 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() { ScopedLock lock( m_mtx ); - T *ptr = m_ptr; - m_ptr = NULL; - return ptr; + return m_ptr.exchange(nullptr); } - // 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. T* GetPtr() const { @@ -77,6 +73,7 @@ public: void SwapPtr(ScopedPtrMT& other) { ScopedLock lock( m_mtx ); + m_ptr.exchange(other.m_ptr.exchange(m_ptr.load())); T * const tmp = other.m_ptr; other.m_ptr = m_ptr; m_ptr = tmp; @@ -91,7 +88,7 @@ public: bool operator!() const throw() { - return m_ptr == NULL; + return m_ptr.load() == nullptr; } // Equality @@ -106,7 +103,7 @@ public: 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. ScopedPtrMT& operator=( T* src ) { @@ -120,16 +117,16 @@ public: } // 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 { - pxAssert(m_ptr != NULL); + pxAssert(m_ptr != nullptr); return *m_ptr; } T* operator->() const { - pxAssert(m_ptr != NULL); + pxAssert(m_ptr != nullptr); return m_ptr; } #endif @@ -137,7 +134,6 @@ public: protected: void _Delete_unlocked() throw() { - delete m_ptr; - m_ptr = NULL; + delete m_ptr.exchange(nullptr); } }; diff --git a/common/include/Utilities/Threading.h b/common/include/Utilities/Threading.h index 6f2cfcb71f..be0244db50 100644 --- a/common/include/Utilities/Threading.h +++ b/common/include/Utilities/Threading.h @@ -192,12 +192,6 @@ namespace Threading extern bool AtomicBitTestAndReset( volatile u32& 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. // Let's not use it. Use mutexes and semaphores instead to create waits. (Air) #if 0 diff --git a/common/src/Utilities/ThreadTools.cpp b/common/src/Utilities/ThreadTools.cpp index 87f071cbdb..324abca580 100644 --- a/common/src/Utilities/ThreadTools.cpp +++ b/common/src/Utilities/ThreadTools.cpp @@ -828,24 +828,6 @@ __fi s32 Threading::AtomicDecrement(volatile s32& Target) { 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 // --------------------------------------------------------------------------------------