mirror of
https://github.com/RetroDECK/Supermodel.git
synced 2025-04-10 19:15:14 +00:00
- CModel3::StopThreads was rather gracelessly killing threads while they were waiting on their semaphores, which works okay Windows but not on Mac OS-X where it was preventing Supermodel from exiting properly. Hence, have instead altered StopThreads to signal to threads that they should exit and wait until until they have all done so. This is much better and is what I should have done the first time around had I not been so lazy :-)!
- Also fixed a small race condition in WakeSoundBoardThread. Previously if it happened to be called just before the sound board thread had finished processing a frame's worth of audio but before it had got around to waiting on the sync condition variable then the wake notification would be lost.
This commit is contained in:
parent
f1e93bcd8f
commit
108ac64de8
|
@ -2169,6 +2169,10 @@ bool CModel3::StartThreads(void)
|
||||||
if (notifySync == NULL)
|
if (notifySync == NULL)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
|
// Reset thread flags
|
||||||
|
pauseThreads = false;
|
||||||
|
stopThreads = false;
|
||||||
|
|
||||||
// Create PPC main board thread, if multi-threading GPU
|
// Create PPC main board thread, if multi-threading GPU
|
||||||
if (g_Config.gpuMultiThreaded)
|
if (g_Config.gpuMultiThreaded)
|
||||||
{
|
{
|
||||||
|
@ -2216,8 +2220,8 @@ bool CModel3::PauseThreads(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Wait for all threads to finish their processing
|
// Let threads know that they should pause and wait for all of them to do so
|
||||||
pausedThreads = true;
|
pauseThreads = true;
|
||||||
while (ppcBrdThreadRunning || sndBrdThreadRunning || drvBrdThreadRunning)
|
while (ppcBrdThreadRunning || sndBrdThreadRunning || drvBrdThreadRunning)
|
||||||
{
|
{
|
||||||
if (!notifySync->Wait(notifyLock))
|
if (!notifySync->Wait(notifyLock))
|
||||||
|
@ -2245,7 +2249,7 @@ bool CModel3::ResumeThreads(void)
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Let all threads know that they can continue running
|
// Let all threads know that they can continue running
|
||||||
pausedThreads = false;
|
pauseThreads = false;
|
||||||
|
|
||||||
// Leave notify critical section
|
// Leave notify critical section
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
|
@ -2258,26 +2262,73 @@ ThreadError:
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::StopThreads(void)
|
bool CModel3::StopThreads(void)
|
||||||
{
|
{
|
||||||
if (!startedThreads)
|
if (!startedThreads)
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
// If sound board thread is unsync'd then remove audio callback
|
// If sound board thread is unsync'd then remove audio callback
|
||||||
if (!syncSndBrdThread)
|
if (!syncSndBrdThread)
|
||||||
SetAudioCallback(NULL, NULL);
|
SetAudioCallback(NULL, NULL);
|
||||||
|
|
||||||
// Pause threads so that can safely delete thread objects
|
// Enter notify critical section
|
||||||
PauseThreads();
|
if (!notifyLock->Lock())
|
||||||
|
goto ThreadError;
|
||||||
|
|
||||||
|
// Let threads know that they should pause and wait for all of them to do so
|
||||||
|
pauseThreads = true;
|
||||||
|
while (ppcBrdThreadRunning || sndBrdThreadRunning || drvBrdThreadRunning)
|
||||||
|
{
|
||||||
|
if (!notifySync->Wait(notifyLock))
|
||||||
|
goto ThreadError;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now let threads know that they should exit
|
||||||
|
stopThreads = true;
|
||||||
|
|
||||||
|
// Leave notify critical section
|
||||||
|
if (!notifyLock->Unlock())
|
||||||
|
goto ThreadError;
|
||||||
|
|
||||||
|
// Resume each thread in turn and wait for them to exit
|
||||||
|
if (ppcBrdThread != NULL)
|
||||||
|
{
|
||||||
|
if (ppcBrdThreadSync->Post())
|
||||||
|
ppcBrdThread->Wait();
|
||||||
|
}
|
||||||
|
if (sndBrdThread != NULL)
|
||||||
|
{
|
||||||
|
if (syncSndBrdThread)
|
||||||
|
{
|
||||||
|
if (sndBrdThreadSync->Post())
|
||||||
|
sndBrdThread->Wait();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (WakeSoundBoardThread())
|
||||||
|
sndBrdThread->Wait();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (drvBrdThread != NULL)
|
||||||
|
{
|
||||||
|
if (drvBrdThreadSync->Post())
|
||||||
|
drvBrdThread->Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete all thread and synchronization objects
|
||||||
DeleteThreadObjects();
|
DeleteThreadObjects();
|
||||||
startedThreads = false;
|
startedThreads = false;
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ThreadError:
|
||||||
|
ErrorLog("Threading error in CModel3::StopThreads: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
|
g_Config.multiThreaded = false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::DeleteThreadObjects(void)
|
void CModel3::DeleteThreadObjects(void)
|
||||||
{
|
{
|
||||||
// Delete (which in turn kills) PPC main board, sound board and drive board threads
|
// Delete PPC main board, sound board and drive board threads
|
||||||
// Note that can do so here safely because threads will always be waiting on their semaphores when this method is called
|
|
||||||
if (ppcBrdThread != NULL)
|
if (ppcBrdThread != NULL)
|
||||||
{
|
{
|
||||||
delete ppcBrdThread;
|
delete ppcBrdThread;
|
||||||
|
@ -2347,40 +2398,37 @@ int CModel3::StartMainBoardThread(void *data)
|
||||||
{
|
{
|
||||||
// Call method on CModel3 to run PPC main board thread
|
// Call method on CModel3 to run PPC main board thread
|
||||||
CModel3 *model3 = (CModel3*)data;
|
CModel3 *model3 = (CModel3*)data;
|
||||||
model3->RunMainBoardThread();
|
return model3->RunMainBoardThread();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CModel3::StartSoundBoardThread(void *data)
|
int CModel3::StartSoundBoardThread(void *data)
|
||||||
{
|
{
|
||||||
// Call method on CModel3 to run sound board thread (unsync'd)
|
// Call method on CModel3 to run sound board thread (unsync'd)
|
||||||
CModel3 *model3 = (CModel3*)data;
|
CModel3 *model3 = (CModel3*)data;
|
||||||
model3->RunSoundBoardThread();
|
return model3->RunSoundBoardThread();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CModel3::StartSoundBoardThreadSyncd(void *data)
|
int CModel3::StartSoundBoardThreadSyncd(void *data)
|
||||||
{
|
{
|
||||||
// Call method on CModel3 to run sound board thread (sync'd)
|
// Call method on CModel3 to run sound board thread (sync'd)
|
||||||
CModel3 *model3 = (CModel3*)data;
|
CModel3 *model3 = (CModel3*)data;
|
||||||
model3->RunSoundBoardThreadSyncd();
|
return model3->RunSoundBoardThreadSyncd();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int CModel3::StartDriveBoardThread(void *data)
|
int CModel3::StartDriveBoardThread(void *data)
|
||||||
{
|
{
|
||||||
// Call method on CModel3 to run drive board thread
|
// Call method on CModel3 to run drive board thread
|
||||||
CModel3 *model3 = (CModel3*)data;
|
CModel3 *model3 = (CModel3*)data;
|
||||||
model3->RunDriveBoardThread();
|
return model3->RunDriveBoardThread();
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::RunMainBoardThread(void)
|
int CModel3::RunMainBoardThread(void)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bool wait = true;
|
bool wait = true;
|
||||||
while (wait)
|
bool exit = false;
|
||||||
|
while (wait && !exit)
|
||||||
{
|
{
|
||||||
// Wait on PPC main board thread semaphore
|
// Wait on PPC main board thread semaphore
|
||||||
if (!ppcBrdThreadSync->Wait())
|
if (!ppcBrdThreadSync->Wait())
|
||||||
|
@ -2390,8 +2438,10 @@ void CModel3::RunMainBoardThread(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Check threads not paused
|
// Check threads are not being stopped or paused
|
||||||
if (!pausedThreads)
|
if (stopThreads)
|
||||||
|
exit = true;
|
||||||
|
else if (!pauseThreads)
|
||||||
{
|
{
|
||||||
wait = false;
|
wait = false;
|
||||||
ppcBrdThreadRunning = true;
|
ppcBrdThreadRunning = true;
|
||||||
|
@ -2401,6 +2451,8 @@ void CModel3::RunMainBoardThread(void)
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
}
|
}
|
||||||
|
if (exit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Process a single frame for PPC main board
|
// Process a single frame for PPC main board
|
||||||
RunMainBoardFrame();
|
RunMainBoardFrame();
|
||||||
|
@ -2423,6 +2475,7 @@ void CModel3::RunMainBoardThread(void)
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in RunMainBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in RunMainBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::AudioCallback(void *data)
|
void CModel3::AudioCallback(void *data)
|
||||||
|
@ -2432,40 +2485,47 @@ void CModel3::AudioCallback(void *data)
|
||||||
model3->WakeSoundBoardThread();
|
model3->WakeSoundBoardThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::WakeSoundBoardThread(void)
|
bool CModel3::WakeSoundBoardThread(void)
|
||||||
{
|
{
|
||||||
// Enter sound board notify critical section
|
// Enter sound board notify critical section
|
||||||
if (!sndBrdNotifyLock->Lock())
|
if (!sndBrdNotifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Signal to sound board thread that it should start processing again
|
// Signal to sound board thread that it should start processing again
|
||||||
|
sndBrdWakeNotify = true;
|
||||||
if (!sndBrdNotifySync->Signal())
|
if (!sndBrdNotifySync->Signal())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Exit sound board notify critical section
|
// Exit sound board notify critical section
|
||||||
if (!sndBrdNotifyLock->Unlock())
|
if (!sndBrdNotifyLock->Unlock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
return;
|
return true;
|
||||||
|
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in WakeSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in WakeSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::RunSoundBoardThread(void)
|
int CModel3::RunSoundBoardThread(void)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bool wait = true;
|
bool wait = true;
|
||||||
while (wait)
|
bool exit = false;
|
||||||
|
while (wait && !exit)
|
||||||
{
|
{
|
||||||
// Enter sound board notify critical section
|
// Enter sound board notify critical section
|
||||||
if (!sndBrdNotifyLock->Lock())
|
if (!sndBrdNotifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Wait for notification from audio callback
|
// Wait for notification from audio callback
|
||||||
if (!sndBrdNotifySync->Wait(sndBrdNotifyLock))
|
while (!sndBrdWakeNotify)
|
||||||
goto ThreadError;
|
{
|
||||||
|
if (!sndBrdNotifySync->Wait(sndBrdNotifyLock))
|
||||||
|
goto ThreadError;
|
||||||
|
}
|
||||||
|
sndBrdWakeNotify = false;
|
||||||
|
|
||||||
// Exit sound board notify critical section
|
// Exit sound board notify critical section
|
||||||
if (!sndBrdNotifyLock->Unlock())
|
if (!sndBrdNotifyLock->Unlock())
|
||||||
|
@ -2475,8 +2535,10 @@ void CModel3::RunSoundBoardThread(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Check threads not paused
|
// Check threads are not being stopped or paused
|
||||||
if (!pausedThreads)
|
if (stopThreads)
|
||||||
|
exit = true;
|
||||||
|
else if (!pauseThreads)
|
||||||
{
|
{
|
||||||
wait = false;
|
wait = false;
|
||||||
sndBrdThreadRunning = true;
|
sndBrdThreadRunning = true;
|
||||||
|
@ -2486,8 +2548,10 @@ void CModel3::RunSoundBoardThread(void)
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
}
|
}
|
||||||
|
if (exit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Keep processing frames until paused or audio buffer is full
|
// Keep processing frames until pausing or audio buffer is full
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
// Enter main notify critical section
|
// Enter main notify critical section
|
||||||
|
@ -2495,7 +2559,7 @@ void CModel3::RunSoundBoardThread(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
paused = pausedThreads;
|
paused = pauseThreads;
|
||||||
|
|
||||||
// Leave main notify critical section
|
// Leave main notify critical section
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
|
@ -2524,14 +2588,16 @@ void CModel3::RunSoundBoardThread(void)
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in RunSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in RunSoundBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::RunSoundBoardThreadSyncd(void)
|
int CModel3::RunSoundBoardThreadSyncd(void)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bool wait = true;
|
bool wait = true;
|
||||||
while (wait)
|
bool exit = false;
|
||||||
|
while (wait && !exit)
|
||||||
{
|
{
|
||||||
// Wait on sound board thread semaphore
|
// Wait on sound board thread semaphore
|
||||||
if (!sndBrdThreadSync->Wait())
|
if (!sndBrdThreadSync->Wait())
|
||||||
|
@ -2541,8 +2607,10 @@ void CModel3::RunSoundBoardThreadSyncd(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Check threads not paused
|
// Check threads are not being stopped or paused
|
||||||
if (!pausedThreads)
|
if (stopThreads)
|
||||||
|
exit = true;
|
||||||
|
else if (!pauseThreads)
|
||||||
{
|
{
|
||||||
wait = false;
|
wait = false;
|
||||||
sndBrdThreadRunning = true;
|
sndBrdThreadRunning = true;
|
||||||
|
@ -2552,6 +2620,8 @@ void CModel3::RunSoundBoardThreadSyncd(void)
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
}
|
}
|
||||||
|
if (exit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Process a single frame for sound board
|
// Process a single frame for sound board
|
||||||
RunSoundBoardFrame();
|
RunSoundBoardFrame();
|
||||||
|
@ -2574,14 +2644,16 @@ void CModel3::RunSoundBoardThreadSyncd(void)
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in RunSoundBoardThreadSyncd: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in RunSoundBoardThreadSyncd: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::RunDriveBoardThread(void)
|
int CModel3::RunDriveBoardThread(void)
|
||||||
{
|
{
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
bool wait = true;
|
bool wait = true;
|
||||||
while (wait)
|
bool exit = false;
|
||||||
|
while (wait && !exit)
|
||||||
{
|
{
|
||||||
// Wait on drive board thread semaphore
|
// Wait on drive board thread semaphore
|
||||||
if (!drvBrdThreadSync->Wait())
|
if (!drvBrdThreadSync->Wait())
|
||||||
|
@ -2591,8 +2663,10 @@ void CModel3::RunDriveBoardThread(void)
|
||||||
if (!notifyLock->Lock())
|
if (!notifyLock->Lock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
|
|
||||||
// Check threads not paused
|
// Check threads are not being stopped or paused
|
||||||
if (!pausedThreads)
|
if (stopThreads)
|
||||||
|
exit = true;
|
||||||
|
else if (!pauseThreads)
|
||||||
{
|
{
|
||||||
wait = false;
|
wait = false;
|
||||||
drvBrdThreadRunning = true;
|
drvBrdThreadRunning = true;
|
||||||
|
@ -2602,6 +2676,8 @@ void CModel3::RunDriveBoardThread(void)
|
||||||
if (!notifyLock->Unlock())
|
if (!notifyLock->Unlock())
|
||||||
goto ThreadError;
|
goto ThreadError;
|
||||||
}
|
}
|
||||||
|
if (exit)
|
||||||
|
return 0;
|
||||||
|
|
||||||
// Process a single frame for drive board
|
// Process a single frame for drive board
|
||||||
RunDriveBoardFrame();
|
RunDriveBoardFrame();
|
||||||
|
@ -2624,6 +2700,7 @@ void CModel3::RunDriveBoardThread(void)
|
||||||
ThreadError:
|
ThreadError:
|
||||||
ErrorLog("Threading error in RunDriveBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
ErrorLog("Threading error in RunDriveBoardThread: %s\nSwitching back to single-threaded mode.\n", CThread::GetLastError());
|
||||||
g_Config.multiThreaded = false;
|
g_Config.multiThreaded = false;
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CModel3::Reset(void)
|
void CModel3::Reset(void)
|
||||||
|
@ -3139,7 +3216,8 @@ CModel3::CModel3(void)
|
||||||
securityPtr = 0;
|
securityPtr = 0;
|
||||||
|
|
||||||
startedThreads = false;
|
startedThreads = false;
|
||||||
pausedThreads = false;
|
pauseThreads = false;
|
||||||
|
stopThreads = false;
|
||||||
ppcBrdThread = NULL;
|
ppcBrdThread = NULL;
|
||||||
sndBrdThread = NULL;
|
sndBrdThread = NULL;
|
||||||
drvBrdThread = NULL;
|
drvBrdThread = NULL;
|
||||||
|
|
|
@ -361,7 +361,7 @@ private:
|
||||||
void RunDriveBoardFrame(void); // Runs drive board for a frame
|
void RunDriveBoardFrame(void); // Runs drive board for a frame
|
||||||
|
|
||||||
bool StartThreads(void); // Starts all threads
|
bool StartThreads(void); // Starts all threads
|
||||||
void StopThreads(void); // Stops all threads
|
bool StopThreads(void); // Stops all threads
|
||||||
void DeleteThreadObjects(void); // Deletes all threads and synchronization objects
|
void DeleteThreadObjects(void); // Deletes all threads and synchronization objects
|
||||||
|
|
||||||
static int StartMainBoardThread(void *data); // Callback to start PPC main board thread
|
static int StartMainBoardThread(void *data); // Callback to start PPC main board thread
|
||||||
|
@ -371,11 +371,11 @@ private:
|
||||||
|
|
||||||
static void AudioCallback(void *data); // Audio buffer callback
|
static void AudioCallback(void *data); // Audio buffer callback
|
||||||
|
|
||||||
void WakeSoundBoardThread(void); // Used by audio callback to wake sound board thread when not sync'd with PPC thread
|
bool WakeSoundBoardThread(void); // Used by audio callback to wake sound board thread (when not sync'd with render thread)
|
||||||
void RunMainBoardThread(void); // Runs PPC main board thread (sync'd in step with render thread)
|
int RunMainBoardThread(void); // Runs PPC main board thread (sync'd in step with render thread)
|
||||||
void RunSoundBoardThread(void); // Runs sound board thread (unsync'd with render thread, ie at full speed)
|
int RunSoundBoardThread(void); // Runs sound board thread (not sync'd in step with render thread, ie running at full speed)
|
||||||
void RunSoundBoardThreadSyncd(void); // Runs sound board thread (sync'd in step with render thread)
|
int RunSoundBoardThreadSyncd(void); // Runs sound board thread (sync'd in step with render thread)
|
||||||
void RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
|
int RunDriveBoardThread(void); // Runs drive board thread (sync'd in step with render thread)
|
||||||
|
|
||||||
// Game and hardware information
|
// Game and hardware information
|
||||||
const struct GameInfo *Game;
|
const struct GameInfo *Game;
|
||||||
|
@ -421,7 +421,8 @@ private:
|
||||||
// Multiple threading
|
// Multiple threading
|
||||||
bool gpusReady; // True if GPUs are ready to render
|
bool gpusReady; // True if GPUs are ready to render
|
||||||
bool startedThreads; // True if threads have been created and started
|
bool startedThreads; // True if threads have been created and started
|
||||||
bool pausedThreads; // True if threads are currently paused
|
bool pauseThreads; // True if threads should pause
|
||||||
|
bool stopThreads; // True if threads should stop
|
||||||
bool syncSndBrdThread; // True if sound board thread should be sync'd in step with render thread
|
bool syncSndBrdThread; // True if sound board thread should be sync'd in step with render thread
|
||||||
CThread *ppcBrdThread; // PPC main board thread
|
CThread *ppcBrdThread; // PPC main board thread
|
||||||
CThread *sndBrdThread; // Sound board thread
|
CThread *sndBrdThread; // Sound board thread
|
||||||
|
@ -430,6 +431,7 @@ private:
|
||||||
bool ppcBrdThreadDone; // Flag to indicate PPC main board thread has finished processing
|
bool ppcBrdThreadDone; // Flag to indicate PPC main board thread has finished processing
|
||||||
bool sndBrdThreadRunning; // Flag to indicate sound board thread is currently processing
|
bool sndBrdThreadRunning; // Flag to indicate sound board thread is currently processing
|
||||||
bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing
|
bool sndBrdThreadDone; // Flag to indicate sound board thread has finished processing
|
||||||
|
bool sndBrdWakeNotify; // Flag to indicate that sound board thread has been woken by audio callback (when not sync'd with render thread)
|
||||||
bool drvBrdThreadRunning; // Flag to indicate drive board thread is currently processing
|
bool drvBrdThreadRunning; // Flag to indicate drive board thread is currently processing
|
||||||
bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing
|
bool drvBrdThreadDone; // Flag to indicate drive board thread has finished processing
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue