all repos — mgba @ 79cfc4fd0a945761bd6d9bbf82c9282af3d4b668

mGBA Game Boy Advance Emulator

Make GBAThreadInterrupt work properly with paused threads again
Jeffrey Pfau jeffrey@endrift.com
Wed, 09 Jul 2014 00:36:04 -0700
commit

79cfc4fd0a945761bd6d9bbf82c9282af3d4b668

parent

ecee71cfa1ccd99ce3de8a0ebb38ba37292439bb

3 files changed, 22 insertions(+), 13 deletions(-)

jump to
M src/gba/gba-thread.csrc/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.hsrc/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.csrc/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;