More thread sync fixes (these mostly only showed up on linux, because of threads starting a lot slower); fixed by including a startup signal to let the creating thread know when the worker has aquired its persistent locks.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2029 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
Jake.Stine 2009-10-18 03:01:10 +00:00
parent 6b0c9cfdfe
commit 877f59a255
6 changed files with 44 additions and 41 deletions

View File

@ -237,8 +237,8 @@ void mtgsThreadObject::OpenPlugin()
void mtgsThreadObject::ExecuteTaskInThread()
{
// Required by the underlying SysThreadBase class (is unlocked on exit)
m_RunningLock.Lock();
m_StartupEvent.Post();
#ifdef RINGBUF_DEBUG_STACK
PacketTagType prevCmd;
@ -247,7 +247,7 @@ void mtgsThreadObject::ExecuteTaskInThread()
pthread_cleanup_push( _clean_close_gs, this );
while( true )
{
m_sem_event.WaitRaw(); // ... because this does a cancel test itself..
m_sem_event.WaitRaw(); // ... because this does a cancel test itself..
StateCheckInThread( false ); // false disables cancel test here!
m_RingBufferIsBusy = true;

View File

@ -47,6 +47,7 @@ void SysThreadBase::Start()
_parent::Start();
m_ExecMode = ExecMode_Closing;
m_sem_event.Post();
m_StartupEvent.Wait();
}
@ -55,6 +56,7 @@ void SysThreadBase::OnStart()
if( !pxAssertDev( m_ExecMode == ExecMode_NoThreadYet, "SysSustainableThread:Start(): Invalid execution mode" ) ) return;
m_ResumeEvent.Reset();
m_StartupEvent.Reset();
FrankenMutex( m_ExecModeMutex );
FrankenMutex( m_RunningLock );
@ -171,20 +173,13 @@ void SysThreadBase::Resume()
ScopedLock locker( m_ExecModeMutex );
// Recursion guard is needed because of the non-blocking Wait if the state
// is Suspending/Closing. Processed events could recurse into Resume, and we'll
// want to silently ignore them.
//RecursionGuard guard( m_resume_guard );
//if( guard.IsReentrant() ) return;
switch( m_ExecMode )
{
case ExecMode_Opened: return;
case ExecMode_NoThreadYet:
Start();
m_ExecMode = ExecMode_Closing;
// fall through...
case ExecMode_Closing:
@ -192,9 +187,7 @@ void SysThreadBase::Resume()
// we need to make sure and wait for the emuThread to enter a fully suspended
// state before continuing...
//locker.Unlock(); // no deadlocks please, thanks. :)
m_RunningLock.Wait();
//locker.Lock();
// The entire state coming out of a Wait is indeterminate because of user input
// and pending messages being handled. If something doesn't feel right, we should
@ -434,7 +427,9 @@ void SysCoreThread::CpuExecute()
void SysCoreThread::ExecuteTaskInThread()
{
m_RunningLock.Lock();
tls_coreThread = this;
m_StartupEvent.Post();
m_sem_event.WaitRaw();
StateCheckInThread();

View File

@ -74,6 +74,11 @@ protected:
// Used to wake up the thread from sleeping when it's in a suspended state.
Semaphore m_ResumeEvent;
// Used to signal the creating thread that the worker has entered the running state.
// This is necessary because until the thread has established itself, locking against
// m_RunningLock isn't a reliable synchronization tool.
Semaphore m_StartupEvent;
// Locked whenever the thread is not in a suspended state (either closed or paused).
// Issue a Wait against this mutex for performing actions that require the thread
// to be suspended.

View File

@ -66,7 +66,8 @@ void AppCoreThread::Resume()
evt.SetInt( CoreStatus_Suspended );
wxGetApp().AddPendingEvent( evt );
sApp.SysExecute();
if( (m_ExecMode != ExecMode_Closing) || (m_ExecMode != ExecMode_Pausing) )
sApp.SysExecute();
}
}

View File

@ -518,6 +518,8 @@ void MainEmuFrame::ReloadRecentLists()
void MainEmuFrame::ApplyCoreStatus()
{
bool valstate = SysHasValidState();
GetMenuBar()->Enable( MenuId_Sys_SuspendResume, SysHasValidState() );
GetMenuBar()->Enable( MenuId_Sys_Reset, SysHasValidState() || (g_plugins!=NULL) );

View File

@ -78,7 +78,7 @@ void MainEmuFrame::Menu_BootCdvd_Click( wxCommandEvent &event )
{
CoreThread.Suspend();
if( !wxFileExists( g_Conf->CurrentIso ) )
if( (g_Conf->CdvdSource == CDVDsrc_Iso) && !wxFileExists(g_Conf->CurrentIso) )
{
if( !_DoSelectIsoBrowser() )
{