Qt: Thread startup improvements
Jeffrey Pfau jeffrey@endrift.com
Sat, 23 Jul 2016 19:02:28 -0700
10 files changed,
46 insertions(+),
13 deletions(-)
M
src/core/thread.c
→
src/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.h
→
src/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.c
→
src/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.c
→
src/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.cpp
→
src/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.cpp
→
src/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.c
→
src/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.c
→
src/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.c
→
src/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;