all repos — mgba @ 4a7dc8bff6fcbf2225634d05a41a18b68bd6b051

mGBA Game Boy Advance Emulator

Qt: Thread startup improvements
Jeffrey Pfau jeffrey@endrift.com
Sat, 23 Jul 2016 19:02:28 -0700
commit

4a7dc8bff6fcbf2225634d05a41a18b68bd6b051

parent

d175a0ac8536a18175a1bc53bd1d9ebe80da2095

M CHANGESCHANGES

@@ -22,6 +22,7 @@ - Qt: Make -g flag work in Qt build

- Qt: Simplify OpenGL context creation - Debugger: Support register and memory writes via GDB stub - GBA Audio: Force audio DMAs to not increment destination + - Qt: Thread startup improvements 0.4.1: (2016-07-11) Bugfixes:
M src/core/thread.csrc/core/thread.c

@@ -109,11 +109,11 @@ struct mCore* core = threadContext->core;

core->setSync(core, &threadContext->sync); core->reset(core); + _changeState(threadContext, THREAD_RUNNING, true); + if (threadContext->startCallback) { threadContext->startCallback(threadContext); } - - _changeState(threadContext, THREAD_RUNNING, true); while (threadContext->state < THREAD_EXITING) { struct mDebugger* debugger = core->debugger;

@@ -303,6 +303,22 @@ _waitUntilNotState(threadContext, THREAD_INTERRUPTING);

MutexUnlock(&threadContext->stateMutex); } +void mCoreThreadInterruptFromThread(struct mCoreThread* threadContext) { + if (!threadContext) { + return; + } + MutexLock(&threadContext->stateMutex); + ++threadContext->interruptDepth; + if (threadContext->interruptDepth > 1 || !mCoreThreadIsActive(threadContext)) { + MutexUnlock(&threadContext->stateMutex); + return; + } + threadContext->savedState = threadContext->state; + threadContext->state = THREAD_INTERRUPTING; + ConditionWake(&threadContext->stateCond); + MutexUnlock(&threadContext->stateMutex); +} + void mCoreThreadContinue(struct mCoreThread* threadContext) { if (!threadContext) { return;

@@ -385,7 +401,6 @@

void mCoreThreadPauseFromThread(struct mCoreThread* threadContext) { bool frameOn = true; MutexLock(&threadContext->stateMutex); - _waitOnInterrupt(threadContext); if (threadContext->state == THREAD_RUNNING) { _pauseThread(threadContext, true); frameOn = false;
M src/core/thread.hsrc/core/thread.h

@@ -72,6 +72,7 @@ void mCoreThreadJoin(struct mCoreThread* threadContext);

bool mCoreThreadIsActive(struct mCoreThread* threadContext); void mCoreThreadInterrupt(struct mCoreThread* threadContext); +void mCoreThreadInterruptFromThread(struct mCoreThread* threadContext); void mCoreThreadContinue(struct mCoreThread* threadContext); void mCoreThreadRunFunction(struct mCoreThread* threadContext, void (*run)(struct mCoreThread*));
M src/feature/commandline.csrc/feature/commandline.c

@@ -124,10 +124,13 @@ }

} argc -= optind; argv += optind; - if (argc != 1) { - return args->showHelp || args->showVersion; + if (argc > 1) { + return false; + } else if (argc == 1) { + args->fname = strdup(argv[0]); + } else { + args->fname = NULL; } - args->fname = strdup(argv[0]); return true; }
M src/platform/example/client-server/server.csrc/platform/example/client-server/server.c

@@ -17,6 +17,10 @@ // Arguments from the command line are parsed by the parseArguments function.

// The NULL here shows that we don't give it any arguments beyond the default ones. struct mArguments args = {}; bool parsed = parseArguments(&args, argc, argv, NULL); + // Parsing can succeed without finding a filename, but we need one. + if (!args.fname) { + parsed = false; + } if (!parsed || args.showHelp) { // If parsing failed, or the user passed --help, show usage. usage(argv[0], NULL);
M src/platform/qt/GDBController.cppsrc/platform/qt/GDBController.cpp

@@ -36,18 +36,15 @@ m_bindAddress.ipv4 = htonl(bindAddress);

} void GDBController::attach() { - if (isAttached() || m_gameController->platform() != PLATFORM_GBA) { + if (isAttached() || (m_gameController->platform() != PLATFORM_GBA && m_gameController->platform() != PLATFORM_NONE)) { return; } - m_gameController->setDebugger(&m_gdbStub.d); if (m_gameController->isLoaded()) { + m_gameController->setDebugger(&m_gdbStub.d); mDebuggerEnter(&m_gdbStub.d, DEBUGGER_ENTER_ATTACHED, 0); } else { QObject::disconnect(m_autoattach); - m_autoattach = connect(m_gameController, &GameController::gameStarted, [this]() { - QObject::disconnect(m_autoattach); - mDebuggerEnter(&m_gdbStub.d, DEBUGGER_ENTER_ATTACHED, 0); - }); + m_autoattach = connect(m_gameController, SIGNAL(gameStarted(mCoreThread*, const QString&)), this, SLOT(attach())); } }
M src/platform/qt/GameController.cppsrc/platform/qt/GameController.cpp

@@ -130,7 +130,10 @@

if (mCoreLoadState(context->core, 0, controller->m_loadStateFlags)) { mCoreDeleteState(context->core, 0); } - QMetaObject::invokeMethod(controller, "gameStarted", Q_ARG(mCoreThread*, context), Q_ARG(const QString&, controller->m_fname)); + + mCoreThreadInterruptFromThread(context); + QMetaObject::invokeMethod(controller, "gameStarted", Qt::BlockingQueuedConnection, Q_ARG(mCoreThread*, context), Q_ARG(const QString&, controller->m_fname)); + mCoreThreadContinue(context); }; m_threadContext.cleanCallback = [](mCoreThread* context) {
M src/platform/sdl/main.csrc/platform/sdl/main.c

@@ -64,6 +64,9 @@ struct mSubParser subparser;

initParserForGraphics(&subparser, &graphicsOpts); bool parsed = parseArguments(&args, argc, argv, &subparser); + if (!args.fname) { + parsed = false; + } if (!parsed || args.showHelp) { usage(argv[0], subparser.usage); freeArguments(&args);
M src/platform/test/fuzz-main.csrc/platform/test/fuzz-main.c

@@ -58,6 +58,9 @@ mCoreConfigSetDefaultValue(&core->config, "idleOptimization", "remove");

struct mArguments args; bool parsed = parseArguments(&args, argc, argv, &subparser); + if (!args.fname) { + parsed = false; + } if (!parsed || args.showHelp) { usage(argv[0], FUZZ_USAGE); core->deinit(core);
M src/platform/test/perf-main.csrc/platform/test/perf-main.c

@@ -93,6 +93,9 @@ };

struct mArguments args = {}; bool parsed = parseArguments(&args, argc, argv, &subparser); + if (!args.fname) { + parsed = false; + } if (!parsed || args.showHelp) { usage(argv[0], PERF_USAGE); didFail = !parsed;