Fixed a memory leak in the MutexLock object.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1984 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-10-08 18:30:40 +00:00
parent 9b213aeffa
commit 46badcc0e8
7 changed files with 74 additions and 34 deletions

View File

@ -99,19 +99,32 @@ namespace Threading
int Count();
};
struct MutexLock
class MutexLock
{
protected:
pthread_mutex_t mutex;
public:
MutexLock();
MutexLock( bool isRecursive );
~MutexLock();
virtual ~MutexLock() throw();
void Lock();
void Unlock();
bool TryLock();
protected:
// empty constructor used by MutexLockRecursive
MutexLock( bool ) {}
};
class MutexLockRecursive : public MutexLock
{
public:
MutexLockRecursive();
virtual ~MutexLockRecursive() throw();
};
// Returns the number of available logical CPUs (cores plus hyperthreaded cpus)
extern void CountLogicalCores( int LogicalCoresPerPhysicalCPU, int PhysicalCoresPerPhysicalCPU );
@ -187,7 +200,7 @@ namespace Threading
pthread_t m_thread;
Semaphore m_sem_event; // general wait event that's needed by most threads.
Semaphore m_sem_finished; // used for canceling and closing threads in a deadlock-safe manner
MutexLock m_lock_start; // used to lock the Start() code from starting simultaneous threads accidentally.
MutexLockRecursive m_lock_start; // used to lock the Start() code from starting simultaneous threads accidentally.
volatile long m_detached; // a boolean value which indicates if the m_thread handle is valid
volatile long m_running; // set true by Start(), and set false by Cancel(), Block(), etc.

View File

@ -48,7 +48,7 @@ namespace Threading
, m_thread()
, m_sem_event()
, m_sem_finished()
, m_lock_start( true ) // recursive mutexing!
, m_lock_start()
, m_detached( true ) // start out with m_thread in detached/invalid state
, m_running( false )
{
@ -572,31 +572,34 @@ namespace Threading
err = pthread_mutex_init( &mutex, NULL );
}
MutexLock::MutexLock( bool isRecursive )
{
if( isRecursive )
{
pthread_mutexattr_t mutexAttribute;
int status = pthread_mutexattr_init( &mutexAttribute );
if (status != 0) { /* ... */ }
status = pthread_mutexattr_settype( &mutexAttribute, PTHREAD_MUTEX_RECURSIVE);
if (status != 0) { /* ... */}
int err = 0;
err = pthread_mutex_init( &mutex, &mutexAttribute );
}
else
{
int err = 0;
err = pthread_mutex_init( &mutex, NULL );
}
}
MutexLock::~MutexLock()
MutexLock::~MutexLock() throw()
{
pthread_mutex_destroy( &mutex );
}
static long _attr_refcount = 0;
static pthread_mutexattr_t _attr_recursive;
MutexLockRecursive::MutexLockRecursive() : MutexLock( false )
{
if( _InterlockedIncrement( &_attr_refcount ) == 1 )
{
if( 0 != pthread_mutexattr_init( &_attr_recursive ) )
throw Exception::OutOfMemory( "Out of memory error initializing the Mutex attributes for recursive mutexing." );
pthread_mutexattr_settype( &_attr_recursive, PTHREAD_MUTEX_RECURSIVE );
}
int err = 0;
err = pthread_mutex_init( &mutex, &_attr_recursive );
}
MutexLockRecursive::~MutexLockRecursive() throw()
{
if( _InterlockedDecrement( &_attr_refcount ) == 0 )
pthread_mutexattr_destroy( &_attr_recursive );
}
void MutexLock::Lock()
{
pthread_mutex_lock( &mutex );

View File

@ -95,7 +95,7 @@ protected:
MutexLock m_lock_RingRestart;
// used to keep multiple threads from sending packets to the ringbuffer concurrently.
MutexLock m_PacketLocker;
MutexLockRecursive m_PacketLocker;
// Used to delay the sending of events. Performance is better if the ringbuffer
// has more than one command in it when the thread is kicked.

View File

@ -94,7 +94,7 @@ mtgsThreadObject::mtgsThreadObject() :
, m_WritePos( 0 )
, m_lock_RingRestart()
, m_PacketLocker( true ) // true - makes it a recursive lock
, m_PacketLocker()
, m_CopyCommandTally( 0 )
, m_CopyDataTally( 0 )

View File

@ -378,3 +378,27 @@ Pcsx2App::~Pcsx2App()
emuLog = NULL;
}
}
// ------------------------------------------------------------------------------------------
// Using the MSVCRT to track memory leaks:
// ------------------------------------------------------------------------------------------
// When exiting PCSX2 normally, the CRT will make a list of all memory that's leaked. The
// number inside {} can be pasted into the line below to cause MSVC to breakpoint on that
// allocation at the time it's made. And then using a stacktrace you can figure out what
// leaked! :D
//
// Limitations: Unfortunately, wxWidgets gui uses a lot of heap allocations while handling
// messages, and so any mouse movements will pretty much screw up the leak value. So to use
// this feature you need to execute pcsx in no-gui mode, and then not move the mouse or use
// the keyboard until you get to the leak. >_<
//
// (but this tool is still still better than nothing!)
struct CrtDebugBreak
{
CrtDebugBreak( int spot )
{
_CrtSetBreakAlloc( spot );
}
};
//CrtDebugBreak breakAt( 157 );

View File

@ -816,10 +816,6 @@
RelativePath="..\..\Vif.h"
>
</File>
<File
RelativePath="..\..\VifDma.cpp"
>
</File>
<File
RelativePath="..\..\Vif0Dma.cpp"
>
@ -828,6 +824,10 @@
RelativePath="..\..\Vif1Dma.cpp"
>
</File>
<File
RelativePath="..\..\VifDma.cpp"
>
</File>
<File
RelativePath="..\..\VifDma.h"
>

View File

@ -215,8 +215,8 @@ Global
{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release SSSE3|Win32.ActiveCfg = Release|Win32
{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release SSSE3|Win32.Build.0 = Release|Win32
{5307BBB7-EBB9-4AA4-8CB6-A94EC473C8C4}.Release SSSE3|x64.ActiveCfg = Release|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Debug|Win32.ActiveCfg = Debug SSE4|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Debug|Win32.Build.0 = Debug SSE4|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Debug|Win32.ActiveCfg = Debug SSE2|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Debug|Win32.Build.0 = Debug SSE2|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Debug|x64.ActiveCfg = Debug|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Devel|Win32.ActiveCfg = Release SSE2|Win32
{18E42F6F-3A62-41EE-B42F-79366C4F1E95}.Devel|Win32.Build.0 = Release SSE2|Win32