Make GBAThreadInterrupt work properly with paused threads again
Jeffrey Pfau jeffrey@endrift.com
Wed, 09 Jul 2014 00:36:04 -0700
3 files changed,
22 insertions(+),
13 deletions(-)
M
src/gba/gba-thread.c
→
src/gba/gba-thread.c
@@ -147,8 +147,12 @@ ARMRun(&cpu);
} } MutexLock(&threadContext->stateMutex); - if (threadContext->state == THREAD_INTERRUPTED) { + if (threadContext->state == THREAD_PAUSING) { threadContext->state = THREAD_PAUSED; + ConditionWake(&threadContext->stateCond); + } + if (threadContext->state == THREAD_INTERRUPTING) { + threadContext->state = THREAD_INTERRUPTED; ConditionWake(&threadContext->stateCond); } while (threadContext->state == THREAD_PAUSED) {@@ -280,15 +284,18 @@ }
free(threadContext->rewindBuffer); } -void GBAThreadTryPause(struct GBAThread* threadContext) { +void GBAThreadInterrupt(struct GBAThread* threadContext) { MutexLock(&threadContext->stateMutex); threadContext->savedState = threadContext->state; - threadContext->state = THREAD_INTERRUPTED; _waitOnInterrupt(threadContext); - threadContext->state = THREAD_PAUSED; + threadContext->state = THREAD_INTERRUPTING; if (threadContext->debugger && threadContext->debugger->state == DEBUGGER_RUNNING) { threadContext->debugger->state = DEBUGGER_EXITING; } + ConditionWake(&threadContext->stateCond); + while (threadContext->state == THREAD_INTERRUPTING) { + ConditionWait(&threadContext->stateCond, &threadContext->stateMutex); + } MutexUnlock(&threadContext->stateMutex); }@@ -304,7 +311,7 @@ if (threadContext->state == THREAD_RUNNING) {
if (threadContext->debugger && threadContext->debugger->state == DEBUGGER_RUNNING) { threadContext->debugger->state = DEBUGGER_EXITING; } - threadContext->state = THREAD_PAUSED; + threadContext->state = THREAD_PAUSING; frameOn = 0; } MutexUnlock(&threadContext->stateMutex);@@ -320,7 +327,7 @@ void GBAThreadUnpause(struct GBAThread* threadContext) {
int frameOn = 1; MutexLock(&threadContext->stateMutex); _waitOnInterrupt(threadContext); - if (threadContext->state == THREAD_PAUSED) { + if (threadContext->state == THREAD_PAUSED || threadContext->state == THREAD_PAUSING) { threadContext->state = THREAD_RUNNING; ConditionWake(&threadContext->stateCond); }
M
src/gba/gba-thread.h
→
src/gba/gba-thread.h
@@ -14,10 +14,12 @@
enum ThreadState { THREAD_INITIALIZED = -1, THREAD_RUNNING = 0, - THREAD_INTERRUPTED = 1, - THREAD_PAUSED = 2, - THREAD_EXITING = 3, - THREAD_SHUTDOWN = 4 + THREAD_INTERRUPTED, + THREAD_INTERRUPTING, + THREAD_PAUSED, + THREAD_PAUSING, + THREAD_EXITING, + THREAD_SHUTDOWN }; struct GBASync {
M
src/platform/sdl/sdl-events.c
→
src/platform/sdl/sdl-events.c
@@ -95,7 +95,7 @@ case SDLK_TAB:
context->sync.audioWait = event->type != SDL_KEYDOWN; return; case SDLK_LEFTBRACKET: - GBAThreadTryPause(context); + GBAThreadInterrupt(context); GBARewind(context, 10); GBAThreadContinue(context); return;@@ -134,7 +134,7 @@ case SDLK_F7:
case SDLK_F8: case SDLK_F9: case SDLK_F10: - GBAThreadTryPause(context); + GBAThreadInterrupt(context); GBASaveState(context->gba, event->keysym.sym - SDLK_F1); GBAThreadContinue(context); break;@@ -153,7 +153,7 @@ case SDLK_F7:
case SDLK_F8: case SDLK_F9: case SDLK_F10: - GBAThreadTryPause(context); + GBAThreadInterrupt(context); GBALoadState(context->gba, event->keysym.sym - SDLK_F1); GBAThreadContinue(context); break;