mirror of https://github.com/PCSX2/pcsx2.git
Common/Threading: Move a bunch of unnecessary wrappers to gui
This commit is contained in:
parent
65e956a01c
commit
e5716922a3
|
@ -20,7 +20,6 @@ target_sources(common PRIVATE
|
||||||
FastFormatString.cpp
|
FastFormatString.cpp
|
||||||
FastJmp.cpp
|
FastJmp.cpp
|
||||||
FileSystem.cpp
|
FileSystem.cpp
|
||||||
Mutex.cpp
|
|
||||||
Misc.cpp
|
Misc.cpp
|
||||||
MD5Digest.cpp
|
MD5Digest.cpp
|
||||||
PathUtils.cpp
|
PathUtils.cpp
|
||||||
|
@ -33,7 +32,6 @@ target_sources(common PRIVATE
|
||||||
StringHelpers.cpp
|
StringHelpers.cpp
|
||||||
StringUtil.cpp
|
StringUtil.cpp
|
||||||
Timer.cpp
|
Timer.cpp
|
||||||
ThreadTools.cpp
|
|
||||||
WindowInfo.cpp
|
WindowInfo.cpp
|
||||||
emitter/bmi.cpp
|
emitter/bmi.cpp
|
||||||
emitter/cpudetect.cpp
|
emitter/cpudetect.cpp
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
|
|
||||||
#if defined(__APPLE__)
|
#if defined(__APPLE__)
|
||||||
|
|
||||||
|
#include <sched.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <mach/mach_init.h>
|
#include <mach/mach_init.h>
|
||||||
#include <mach/thread_act.h>
|
#include <mach/thread_act.h>
|
||||||
|
@ -32,6 +33,11 @@ __forceinline void Threading::Sleep(int ms)
|
||||||
usleep(1000 * ms);
|
usleep(1000 * ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline void Threading::Timeslice()
|
||||||
|
{
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
|
|
||||||
// For use in spin/wait loops, acts as a hint to Intel CPUs and should, in theory
|
// For use in spin/wait loops, acts as a hint to Intel CPUs and should, in theory
|
||||||
// improve performance and reduce cpu power consumption.
|
// improve performance and reduce cpu power consumption.
|
||||||
__forceinline void Threading::SpinWait()
|
__forceinline void Threading::SpinWait()
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include "common/Dependencies.h" // _ macro
|
#include "common/Dependencies.h" // _ macro
|
||||||
#include "common/Threading.h"
|
#include "common/Threading.h"
|
||||||
#include "common/General.h"
|
#include "common/General.h"
|
||||||
|
#include "common/StringHelpers.h"
|
||||||
|
|
||||||
// for lack of a better place...
|
// for lack of a better place...
|
||||||
Fnptr_OutOfMemory pxDoOutOfMemory = NULL;
|
Fnptr_OutOfMemory pxDoOutOfMemory = NULL;
|
||||||
|
|
|
@ -55,6 +55,11 @@ __forceinline void Threading::Sleep(int ms)
|
||||||
usleep(1000 * ms);
|
usleep(1000 * ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__forceinline void Threading::Timeslice()
|
||||||
|
{
|
||||||
|
sched_yield();
|
||||||
|
}
|
||||||
|
|
||||||
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
|
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
|
||||||
// improve performance and reduce cpu power consumption.
|
// improve performance and reduce cpu power consumption.
|
||||||
__forceinline void Threading::SpinWait()
|
__forceinline void Threading::SpinWait()
|
||||||
|
|
|
@ -14,11 +14,14 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/Threading.h"
|
#include "common/Threading.h"
|
||||||
|
#include "common/Assertions.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "common/RedtapeWindows.h"
|
#include "common/RedtapeWindows.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <limits>
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
// Semaphore Implementations
|
// Semaphore Implementations
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -168,4 +171,4 @@ bool Threading::KernelSemaphore::TryWait()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "common/Threading.h"
|
|
||||||
|
|
||||||
void Threading::pxTestCancel()
|
|
||||||
{
|
|
||||||
pthread_testcancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
__fi void Threading::Timeslice()
|
|
||||||
{
|
|
||||||
sched_yield();
|
|
||||||
}
|
|
|
@ -15,21 +15,15 @@
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <wx/datetime.h>
|
|
||||||
#ifdef _WIN32
|
|
||||||
// thanks I hate it.
|
|
||||||
#include <wx/filefn.h>
|
|
||||||
#define HAVE_MODE_T
|
|
||||||
#endif
|
|
||||||
#include <semaphore.h>
|
|
||||||
#include <errno.h> // EBUSY
|
|
||||||
#include <pthread.h>
|
|
||||||
#ifdef __APPLE__
|
|
||||||
#include <mach/semaphore.h>
|
|
||||||
#endif
|
|
||||||
#include "common/Pcsx2Defs.h"
|
#include "common/Pcsx2Defs.h"
|
||||||
#include "common/TraceLog.h"
|
|
||||||
#include "common/General.h"
|
#include "common/General.h"
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <mach/semaphore.h>
|
||||||
|
#elif !defined(_WIN32)
|
||||||
|
#include <semaphore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
// --------------------------------------------------------------------------------------
|
||||||
|
@ -52,12 +46,11 @@
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
{
|
{
|
||||||
class ThreadHandle;
|
// --------------------------------------------------------------------------------------
|
||||||
class pxThread;
|
// Platform Specific External APIs
|
||||||
class RwMutex;
|
// --------------------------------------------------------------------------------------
|
||||||
|
// The following set of documented functions have Linux/Win32 specific implementations,
|
||||||
extern void pxTestCancel();
|
// which are found in WinThreads.cpp and LnxThreads.cpp
|
||||||
extern void YieldToMain();
|
|
||||||
|
|
||||||
extern u64 GetThreadCpuTime();
|
extern u64 GetThreadCpuTime();
|
||||||
extern u64 GetThreadTicksPerSecond();
|
extern u64 GetThreadTicksPerSecond();
|
||||||
|
@ -65,17 +58,6 @@ namespace Threading
|
||||||
/// Set the name of the current thread
|
/// Set the name of the current thread
|
||||||
extern void SetNameOfCurrentThread(const char* name);
|
extern void SetNameOfCurrentThread(const char* name);
|
||||||
|
|
||||||
extern const wxTimeSpan def_yieldgui_interval;
|
|
||||||
} // namespace Threading
|
|
||||||
|
|
||||||
namespace Threading
|
|
||||||
{
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// Platform Specific External APIs
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// The following set of documented functions have Linux/Win32 specific implementations,
|
|
||||||
// which are found in WinThreads.cpp and LnxThreads.cpp
|
|
||||||
|
|
||||||
// Releases a timeslice to other threads.
|
// Releases a timeslice to other threads.
|
||||||
extern void Timeslice();
|
extern void Timeslice();
|
||||||
|
|
||||||
|
@ -129,44 +111,6 @@ namespace Threading
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// NonblockingMutex
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// This is a very simple non-blocking mutex, which behaves similarly to pthread_mutex's
|
|
||||||
// trylock(), but without any of the extra overhead needed to set up a structure capable
|
|
||||||
// of blocking waits. It basically optimizes to a single InterlockedExchange.
|
|
||||||
//
|
|
||||||
// Simple use: if TryAcquire() returns false, the Bool is already interlocked by another thread.
|
|
||||||
// If TryAcquire() returns true, you've locked the object and are *responsible* for unlocking
|
|
||||||
// it later.
|
|
||||||
//
|
|
||||||
class NonblockingMutex
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
std::atomic_flag val;
|
|
||||||
|
|
||||||
public:
|
|
||||||
NonblockingMutex() { val.clear(); }
|
|
||||||
virtual ~NonblockingMutex() = default;
|
|
||||||
|
|
||||||
bool TryAcquire() noexcept
|
|
||||||
{
|
|
||||||
return !val.test_and_set();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Can be done with a TryAcquire/Release but it is likely better to do it outside of the object
|
|
||||||
bool IsLocked()
|
|
||||||
{
|
|
||||||
pxAssertMsg(0, "IsLocked isn't supported for NonblockingMutex");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Release()
|
|
||||||
{
|
|
||||||
val.clear();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/// A semaphore that may not have a fast userspace path
|
/// A semaphore that may not have a fast userspace path
|
||||||
/// (Used in other semaphore-based algorithms where the semaphore is just used for its thread sleep/wake ability)
|
/// (Used in other semaphore-based algorithms where the semaphore is just used for its thread sleep/wake ability)
|
||||||
class KernelSemaphore
|
class KernelSemaphore
|
||||||
|
@ -261,92 +205,4 @@ namespace Threading
|
||||||
/// Should be called by the worker thread if it restarts after dying
|
/// Should be called by the worker thread if it restarts after dying
|
||||||
void Reset();
|
void Reset();
|
||||||
};
|
};
|
||||||
|
|
||||||
class Mutex
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
pthread_mutex_t m_mutex;
|
|
||||||
|
|
||||||
public:
|
|
||||||
Mutex();
|
|
||||||
virtual ~Mutex();
|
|
||||||
virtual bool IsRecursive() const { return false; }
|
|
||||||
|
|
||||||
void Recreate();
|
|
||||||
bool RecreateIfLocked();
|
|
||||||
void Detach();
|
|
||||||
|
|
||||||
void Acquire();
|
|
||||||
bool Acquire(const wxTimeSpan& timeout);
|
|
||||||
bool TryAcquire();
|
|
||||||
void Release();
|
|
||||||
|
|
||||||
void AcquireWithoutYield();
|
|
||||||
bool AcquireWithoutYield(const wxTimeSpan& timeout);
|
|
||||||
|
|
||||||
void Wait();
|
|
||||||
void WaitWithSpin();
|
|
||||||
bool Wait(const wxTimeSpan& timeout);
|
|
||||||
void WaitWithoutYield();
|
|
||||||
bool WaitWithoutYield(const wxTimeSpan& timeout);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// empty constructor used by MutexLockRecursive
|
|
||||||
Mutex(bool) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
class MutexRecursive : public Mutex
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MutexRecursive();
|
|
||||||
virtual ~MutexRecursive();
|
|
||||||
virtual bool IsRecursive() const { return true; }
|
|
||||||
};
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ScopedLock
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// Helper class for using Mutexes. Using this class provides an exception-safe (and
|
|
||||||
// generally clean) method of locking code inside a function or conditional block. The lock
|
|
||||||
// will be automatically released on any return or exit from the function.
|
|
||||||
//
|
|
||||||
// Const qualification note:
|
|
||||||
// ScopedLock takes const instances of the mutex, even though the mutex is modified
|
|
||||||
// by locking and unlocking. Two rationales:
|
|
||||||
//
|
|
||||||
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
|
|
||||||
// this class needs a const hack to allow those accessors to be const (which is typically
|
|
||||||
// *very* important).
|
|
||||||
//
|
|
||||||
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
|
|
||||||
// scope exits, by any means. Only via manual calls to Release or Acquire does that
|
|
||||||
// change, and typically those are only used in very special circumstances of their own.
|
|
||||||
//
|
|
||||||
class ScopedLock
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(ScopedLock);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Mutex* m_lock;
|
|
||||||
bool m_IsLocked;
|
|
||||||
|
|
||||||
public:
|
|
||||||
virtual ~ScopedLock();
|
|
||||||
explicit ScopedLock(const Mutex* locker = NULL);
|
|
||||||
explicit ScopedLock(const Mutex& locker);
|
|
||||||
void AssignAndLock(const Mutex& locker);
|
|
||||||
void AssignAndLock(const Mutex* locker);
|
|
||||||
|
|
||||||
void Assign(const Mutex& locker);
|
|
||||||
void Assign(const Mutex* locker);
|
|
||||||
|
|
||||||
void Release();
|
|
||||||
void Acquire();
|
|
||||||
|
|
||||||
bool IsLocked() const { return m_IsLocked; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Special constructor used by ScopedTryLock
|
|
||||||
ScopedLock(const Mutex& locker, bool isTryLock);
|
|
||||||
};
|
|
||||||
} // namespace Threading
|
} // namespace Threading
|
||||||
|
|
|
@ -24,6 +24,11 @@ __fi void Threading::Sleep(int ms)
|
||||||
::Sleep(ms);
|
::Sleep(ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__fi void Threading::Timeslice()
|
||||||
|
{
|
||||||
|
::Sleep(0);
|
||||||
|
}
|
||||||
|
|
||||||
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
|
// For use in spin/wait loops, Acts as a hint to Intel CPUs and should, in theory
|
||||||
// improve performance and reduce cpu power consumption.
|
// improve performance and reduce cpu power consumption.
|
||||||
__fi void Threading::SpinWait()
|
__fi void Threading::SpinWait()
|
||||||
|
|
|
@ -98,9 +98,7 @@
|
||||||
<ClCompile Include="Windows\WinMisc.cpp" />
|
<ClCompile Include="Windows\WinMisc.cpp" />
|
||||||
<ClCompile Include="Windows\WinThreads.cpp" />
|
<ClCompile Include="Windows\WinThreads.cpp" />
|
||||||
<ClCompile Include="Misc.cpp" />
|
<ClCompile Include="Misc.cpp" />
|
||||||
<ClCompile Include="Mutex.cpp" />
|
|
||||||
<ClCompile Include="Semaphore.cpp" />
|
<ClCompile Include="Semaphore.cpp" />
|
||||||
<ClCompile Include="ThreadTools.cpp" />
|
|
||||||
<ClCompile Include="emitter\bmi.cpp" />
|
<ClCompile Include="emitter\bmi.cpp" />
|
||||||
<ClCompile Include="emitter\cpudetect.cpp" />
|
<ClCompile Include="emitter\cpudetect.cpp" />
|
||||||
<ClCompile Include="emitter\fpu.cpp" />
|
<ClCompile Include="emitter\fpu.cpp" />
|
||||||
|
|
|
@ -52,9 +52,6 @@
|
||||||
<ClCompile Include="Misc.cpp">
|
<ClCompile Include="Misc.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="Mutex.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="PathUtils.cpp">
|
<ClCompile Include="PathUtils.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -76,9 +73,6 @@
|
||||||
<ClCompile Include="StringHelpers.cpp">
|
<ClCompile Include="StringHelpers.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="ThreadTools.cpp">
|
|
||||||
<Filter>Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="VirtualMemory.cpp">
|
<ClCompile Include="VirtualMemory.cpp">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
namespace x86Emitter
|
namespace x86Emitter
|
||||||
{
|
{
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
//------------------------------------------------------------------
|
//------------------------------------------------------------------
|
||||||
|
|
||||||
#include "common/emitter/legacy_internal.h"
|
#include "common/emitter/legacy_internal.h"
|
||||||
|
#include "common/Console.h"
|
||||||
|
|
||||||
emitterT void ModRM(uint mod, uint reg, uint rm)
|
emitterT void ModRM(uint mod, uint reg, uint rm)
|
||||||
{
|
{
|
||||||
|
|
|
@ -16,6 +16,8 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "common/Threading.h"
|
#include "common/Threading.h"
|
||||||
|
#include "common/Assertions.h"
|
||||||
|
#include "common/Pcsx2Defs.h"
|
||||||
|
|
||||||
static const uint iREGCNT_XMM = 16;
|
static const uint iREGCNT_XMM = 16;
|
||||||
static const uint iREGCNT_GPR = 16;
|
static const uint iREGCNT_GPR = 16;
|
||||||
|
|
|
@ -1119,6 +1119,7 @@ set(pcsx2GuiSources
|
||||||
gui/MainFrame.cpp
|
gui/MainFrame.cpp
|
||||||
gui/MainMenuClicks.cpp
|
gui/MainMenuClicks.cpp
|
||||||
gui/MessageBoxes.cpp
|
gui/MessageBoxes.cpp
|
||||||
|
gui/Mutex.cpp
|
||||||
gui/MSWstuff.cpp
|
gui/MSWstuff.cpp
|
||||||
gui/Panels/BaseApplicableConfigPanel.cpp
|
gui/Panels/BaseApplicableConfigPanel.cpp
|
||||||
gui/Panels/BiosSelectorPanel.cpp
|
gui/Panels/BiosSelectorPanel.cpp
|
||||||
|
@ -1195,7 +1196,6 @@ set(pcsx2GuiHeaders
|
||||||
gui/pxStaticText.h
|
gui/pxStaticText.h
|
||||||
gui/RecentIsoList.h
|
gui/RecentIsoList.h
|
||||||
gui/Saveslots.h
|
gui/Saveslots.h
|
||||||
gui/ScopedPtrMT.h
|
|
||||||
gui/SysThreads.h
|
gui/SysThreads.h
|
||||||
gui/ThreadingDialogs.h
|
gui/ThreadingDialogs.h
|
||||||
gui/ThreadingDialogs.cpp
|
gui/ThreadingDialogs.cpp
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
* If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "common/Threading.h"
|
#include "PersistentThread.h"
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
{
|
{
|
|
@ -17,7 +17,16 @@
|
||||||
|
|
||||||
#include "common/Threading.h"
|
#include "common/Threading.h"
|
||||||
#include "common/EventSource.h"
|
#include "common/EventSource.h"
|
||||||
#include "ScopedPtrMT.h"
|
#include "common/Console.h"
|
||||||
|
#include "common/TraceLog.h"
|
||||||
|
#include <wx/datetime.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#ifdef __APPLE__
|
||||||
|
#include <mach/semaphore.h>
|
||||||
|
#else
|
||||||
|
#include <semaphore.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#undef Yield // release the burden of windows.h global namespace spam.
|
#undef Yield // release the burden of windows.h global namespace spam.
|
||||||
|
|
||||||
|
@ -113,12 +122,227 @@ namespace Exception
|
||||||
|
|
||||||
namespace Threading
|
namespace Threading
|
||||||
{
|
{
|
||||||
|
extern void pxTestCancel();
|
||||||
|
extern void YieldToMain();
|
||||||
|
|
||||||
|
extern const wxTimeSpan def_yieldgui_interval;
|
||||||
|
|
||||||
extern pxThread* pxGetCurrentThread();
|
extern pxThread* pxGetCurrentThread();
|
||||||
extern wxString pxGetCurrentThreadName();
|
extern wxString pxGetCurrentThreadName();
|
||||||
extern bool _WaitGui_RecursionGuard(const wxChar* name);
|
extern bool _WaitGui_RecursionGuard(const wxChar* name);
|
||||||
|
|
||||||
extern bool AllowDeletions();
|
extern bool AllowDeletions();
|
||||||
|
|
||||||
|
class Mutex
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
pthread_mutex_t m_mutex;
|
||||||
|
|
||||||
|
public:
|
||||||
|
Mutex();
|
||||||
|
virtual ~Mutex();
|
||||||
|
virtual bool IsRecursive() const { return false; }
|
||||||
|
|
||||||
|
void Recreate();
|
||||||
|
bool RecreateIfLocked();
|
||||||
|
void Detach();
|
||||||
|
|
||||||
|
void Acquire();
|
||||||
|
bool Acquire(const wxTimeSpan& timeout);
|
||||||
|
bool TryAcquire();
|
||||||
|
void Release();
|
||||||
|
|
||||||
|
void AcquireWithoutYield();
|
||||||
|
bool AcquireWithoutYield(const wxTimeSpan& timeout);
|
||||||
|
|
||||||
|
void Wait();
|
||||||
|
void WaitWithSpin();
|
||||||
|
bool Wait(const wxTimeSpan& timeout);
|
||||||
|
void WaitWithoutYield();
|
||||||
|
bool WaitWithoutYield(const wxTimeSpan& timeout);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// empty constructor used by MutexLockRecursive
|
||||||
|
Mutex(bool) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
class MutexRecursive : public Mutex
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
MutexRecursive();
|
||||||
|
virtual ~MutexRecursive();
|
||||||
|
virtual bool IsRecursive() const { return true; }
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// ScopedLock
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// Helper class for using Mutexes. Using this class provides an exception-safe (and
|
||||||
|
// generally clean) method of locking code inside a function or conditional block. The lock
|
||||||
|
// will be automatically released on any return or exit from the function.
|
||||||
|
//
|
||||||
|
// Const qualification note:
|
||||||
|
// ScopedLock takes const instances of the mutex, even though the mutex is modified
|
||||||
|
// by locking and unlocking. Two rationales:
|
||||||
|
//
|
||||||
|
// 1) when designing classes with accessors (GetString, GetValue, etc) that need mutexes,
|
||||||
|
// this class needs a const hack to allow those accessors to be const (which is typically
|
||||||
|
// *very* important).
|
||||||
|
//
|
||||||
|
// 2) The state of the Mutex is guaranteed to be unchanged when the calling function or
|
||||||
|
// scope exits, by any means. Only via manual calls to Release or Acquire does that
|
||||||
|
// change, and typically those are only used in very special circumstances of their own.
|
||||||
|
//
|
||||||
|
class ScopedLock
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject(ScopedLock);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Mutex* m_lock;
|
||||||
|
bool m_IsLocked;
|
||||||
|
|
||||||
|
public:
|
||||||
|
virtual ~ScopedLock();
|
||||||
|
explicit ScopedLock(const Mutex* locker = NULL);
|
||||||
|
explicit ScopedLock(const Mutex& locker);
|
||||||
|
void AssignAndLock(const Mutex& locker);
|
||||||
|
void AssignAndLock(const Mutex* locker);
|
||||||
|
|
||||||
|
void Assign(const Mutex& locker);
|
||||||
|
void Assign(const Mutex* locker);
|
||||||
|
|
||||||
|
void Release();
|
||||||
|
void Acquire();
|
||||||
|
|
||||||
|
bool IsLocked() const { return m_IsLocked; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
// Special constructor used by ScopedTryLock
|
||||||
|
ScopedLock(const Mutex& locker, bool isTryLock);
|
||||||
|
};
|
||||||
|
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
// ScopedPtrMT
|
||||||
|
// --------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class ScopedPtrMT
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject(ScopedPtrMT);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
std::atomic<T*> m_ptr;
|
||||||
|
Threading::Mutex m_mtx;
|
||||||
|
|
||||||
|
public:
|
||||||
|
typedef T element_type;
|
||||||
|
|
||||||
|
wxEXPLICIT ScopedPtrMT(T* ptr = nullptr)
|
||||||
|
{
|
||||||
|
m_ptr = ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
~ScopedPtrMT() { _Delete_unlocked(); }
|
||||||
|
|
||||||
|
ScopedPtrMT& Reassign(T* ptr = nullptr)
|
||||||
|
{
|
||||||
|
T* doh = m_ptr.exchange(ptr);
|
||||||
|
if (ptr != doh)
|
||||||
|
delete doh;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ScopedPtrMT& Delete() noexcept
|
||||||
|
{
|
||||||
|
ScopedLock lock(m_mtx);
|
||||||
|
_Delete_unlocked();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes the pointer from scoped management, but does not delete!
|
||||||
|
// (ScopedPtr will be nullptr after this method)
|
||||||
|
T* DetachPtr()
|
||||||
|
{
|
||||||
|
ScopedLock lock(m_mtx);
|
||||||
|
|
||||||
|
return m_ptr.exchange(nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
|
||||||
|
// has no object in management.
|
||||||
|
T* GetPtr() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// ScopedPtrMT Operators
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// I've decided to use the ATL's approach to pointer validity tests, opposed to
|
||||||
|
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
|
||||||
|
// allow the T* implicit casting.
|
||||||
|
|
||||||
|
bool operator!() const noexcept
|
||||||
|
{
|
||||||
|
return m_ptr.load() == nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Equality
|
||||||
|
bool operator==(T* pT) const noexcept
|
||||||
|
{
|
||||||
|
return m_ptr == pT;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inequality
|
||||||
|
bool operator!=(T* pT) const noexcept
|
||||||
|
{
|
||||||
|
return !operator==(pT);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
|
||||||
|
// of the managed pointer.
|
||||||
|
ScopedPtrMT& operator=(T* src)
|
||||||
|
{
|
||||||
|
return Reassign(src);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
operator T*() const
|
||||||
|
{
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dereference operator, returns a handle to the managed pointer.
|
||||||
|
// Generates a debug assertion if the object is nullptr!
|
||||||
|
T& operator*() const
|
||||||
|
{
|
||||||
|
pxAssert(m_ptr != nullptr);
|
||||||
|
return *m_ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T* operator->() const
|
||||||
|
{
|
||||||
|
pxAssert(m_ptr != nullptr);
|
||||||
|
return m_ptr;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void _Delete_unlocked() noexcept
|
||||||
|
{
|
||||||
|
delete m_ptr.exchange(nullptr);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
// RecursionGuard - Basic protection against function recursion
|
// RecursionGuard - Basic protection against function recursion
|
||||||
// ----------------------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -1,140 +0,0 @@
|
||||||
/* PCSX2 - PS2 Emulator for PCs
|
|
||||||
* Copyright (C) 2002-2010 PCSX2 Dev Team
|
|
||||||
*
|
|
||||||
* PCSX2 is free software: you can redistribute it and/or modify it under the terms
|
|
||||||
* of the GNU Lesser General Public License as published by the Free Software Found-
|
|
||||||
* ation, either version 3 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* PCSX2 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
|
|
||||||
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE. See the GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License along with PCSX2.
|
|
||||||
* If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "common/Threading.h"
|
|
||||||
using Threading::ScopedLock;
|
|
||||||
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
// ScopedPtrMT
|
|
||||||
// --------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
class ScopedPtrMT
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(ScopedPtrMT);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
std::atomic<T*> m_ptr;
|
|
||||||
Threading::Mutex m_mtx;
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef T element_type;
|
|
||||||
|
|
||||||
wxEXPLICIT ScopedPtrMT(T* ptr = nullptr)
|
|
||||||
{
|
|
||||||
m_ptr = ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
~ScopedPtrMT() { _Delete_unlocked(); }
|
|
||||||
|
|
||||||
ScopedPtrMT& Reassign(T* ptr = nullptr)
|
|
||||||
{
|
|
||||||
T* doh = m_ptr.exchange(ptr);
|
|
||||||
if (ptr != doh)
|
|
||||||
delete doh;
|
|
||||||
return *this;
|
|
||||||
}
|
|
||||||
|
|
||||||
ScopedPtrMT& Delete() noexcept
|
|
||||||
{
|
|
||||||
ScopedLock lock(m_mtx);
|
|
||||||
_Delete_unlocked();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removes the pointer from scoped management, but does not delete!
|
|
||||||
// (ScopedPtr will be nullptr after this method)
|
|
||||||
T* DetachPtr()
|
|
||||||
{
|
|
||||||
ScopedLock lock(m_mtx);
|
|
||||||
|
|
||||||
return m_ptr.exchange(nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Returns the managed pointer. Can return nullptr as a valid result if the ScopedPtrMT
|
|
||||||
// has no object in management.
|
|
||||||
T* GetPtr() const
|
|
||||||
{
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// ScopedPtrMT Operators
|
|
||||||
// ----------------------------------------------------------------------------
|
|
||||||
// I've decided to use the ATL's approach to pointer validity tests, opposed to
|
|
||||||
// the wx/boost approach (which uses some bizarre member method pointer crap, and can't
|
|
||||||
// allow the T* implicit casting.
|
|
||||||
|
|
||||||
bool operator!() const noexcept
|
|
||||||
{
|
|
||||||
return m_ptr.load() == nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Equality
|
|
||||||
bool operator==(T* pT) const noexcept
|
|
||||||
{
|
|
||||||
return m_ptr == pT;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Inequality
|
|
||||||
bool operator!=(T* pT) const noexcept
|
|
||||||
{
|
|
||||||
return !operator==(pT);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convenient assignment operator. ScopedPtrMT = nullptr will issue an automatic deletion
|
|
||||||
// of the managed pointer.
|
|
||||||
ScopedPtrMT& operator=(T* src)
|
|
||||||
{
|
|
||||||
return Reassign(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
operator T*() const
|
|
||||||
{
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dereference operator, returns a handle to the managed pointer.
|
|
||||||
// Generates a debug assertion if the object is nullptr!
|
|
||||||
T& operator*() const
|
|
||||||
{
|
|
||||||
pxAssert(m_ptr != nullptr);
|
|
||||||
return *m_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
T* operator->() const
|
|
||||||
{
|
|
||||||
pxAssert(m_ptr != nullptr);
|
|
||||||
return m_ptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void _Delete_unlocked() noexcept
|
|
||||||
{
|
|
||||||
delete m_ptr.exchange(nullptr);
|
|
||||||
}
|
|
||||||
};
|
|
|
@ -354,6 +354,7 @@
|
||||||
<ClCompile Include="gui\Dialogs\McdConfigDialog.cpp" />
|
<ClCompile Include="gui\Dialogs\McdConfigDialog.cpp" />
|
||||||
<ClCompile Include="gui\DriveList.cpp" />
|
<ClCompile Include="gui\DriveList.cpp" />
|
||||||
<ClCompile Include="gui\IniInterface.cpp" />
|
<ClCompile Include="gui\IniInterface.cpp" />
|
||||||
|
<ClCompile Include="gui\Mutex.cpp" />
|
||||||
<ClCompile Include="gui\Panels\MemoryCardListView.cpp" />
|
<ClCompile Include="gui\Panels\MemoryCardListView.cpp" />
|
||||||
<ClCompile Include="gui\PersistentThread.cpp" />
|
<ClCompile Include="gui\PersistentThread.cpp" />
|
||||||
<ClCompile Include="gui\pxCheckBox.cpp" />
|
<ClCompile Include="gui\pxCheckBox.cpp" />
|
||||||
|
@ -818,7 +819,6 @@
|
||||||
<ClInclude Include="gui\Debugger\DebuggerLists.h" />
|
<ClInclude Include="gui\Debugger\DebuggerLists.h" />
|
||||||
<ClInclude Include="gui\Debugger\DisassemblyDialog.h" />
|
<ClInclude Include="gui\Debugger\DisassemblyDialog.h" />
|
||||||
<ClInclude Include="gui\Panels\MemoryCardPanels.h" />
|
<ClInclude Include="gui\Panels\MemoryCardPanels.h" />
|
||||||
<ClInclude Include="gui\ScopedPtrMT.h" />
|
|
||||||
<ClInclude Include="gui\ThreadingDialogs.h" />
|
<ClInclude Include="gui\ThreadingDialogs.h" />
|
||||||
<ClInclude Include="gui\wxAppWithHelpers.h" />
|
<ClInclude Include="gui\wxAppWithHelpers.h" />
|
||||||
<ClInclude Include="gui\wxSettingsInterface.h" />
|
<ClInclude Include="gui\wxSettingsInterface.h" />
|
||||||
|
|
|
@ -1769,7 +1769,12 @@
|
||||||
<ClCompile Include="GS\Renderers\DX12\GSDevice12.cpp">
|
<ClCompile Include="GS\Renderers\DX12\GSDevice12.cpp">
|
||||||
<Filter>System\Ps2\GS\Renderers\Direct3D12</Filter>
|
<Filter>System\Ps2\GS\Renderers\Direct3D12</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="gui\PersistentThread.cpp" />
|
<ClCompile Include="gui\Mutex.cpp">
|
||||||
|
<Filter>AppHost</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="gui\PersistentThread.cpp">
|
||||||
|
<Filter>AppHost</Filter>
|
||||||
|
</ClCompile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Patch.h">
|
<ClInclude Include="Patch.h">
|
||||||
|
@ -2946,8 +2951,9 @@
|
||||||
<ClInclude Include="GS\Renderers\DX12\GSTexture12.h">
|
<ClInclude Include="GS\Renderers\DX12\GSTexture12.h">
|
||||||
<Filter>System\Ps2\GS\Renderers\Direct3D12</Filter>
|
<Filter>System\Ps2\GS\Renderers\Direct3D12</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
<ClInclude Include="gui\ScopedPtrMT.h" />
|
<ClInclude Include="gui\PersistentThread.h">
|
||||||
<ClInclude Include="gui\PersistentThread.h" />
|
<Filter>AppHost</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ResourceCompile Include="windows\wxResources.rc">
|
<ResourceCompile Include="windows\wxResources.rc">
|
||||||
|
|
Loading…
Reference in New Issue