Qt: Thread startup improvements

This commit is contained in:
Jeffrey Pfau 2016-07-23 19:02:28 -07:00
parent d175a0ac85
commit 4a7dc8bff6
10 changed files with 46 additions and 13 deletions

View File

@ -22,6 +22,7 @@ Misc:
- 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:

View File

@ -109,12 +109,12 @@ static THREAD_ENTRY _mCoreThreadRun(void* context) {
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;
if (debugger) {
@ -303,6 +303,22 @@ void mCoreThreadInterrupt(struct mCoreThread* threadContext) {
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 mCoreThreadTogglePause(struct mCoreThread* threadContext) {
void mCoreThreadPauseFromThread(struct mCoreThread* threadContext) {
bool frameOn = true;
MutexLock(&threadContext->stateMutex);
_waitOnInterrupt(threadContext);
if (threadContext->state == THREAD_RUNNING) {
_pauseThread(threadContext, true);
frameOn = false;

View File

@ -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*));

View File

@ -124,10 +124,13 @@ bool parseArguments(struct mArguments* args, int argc, char* const* argv, struct
}
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;
}

View File

@ -17,6 +17,10 @@ int main(int argc, char** argv) {
// 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);

View File

@ -36,18 +36,15 @@ void GDBController::setBindAddress(uint32_t 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()));
}
}

View File

@ -130,7 +130,10 @@ GameController::GameController(QObject* parent)
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) {

View File

@ -64,6 +64,9 @@ int main(int argc, char** argv) {
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);

View File

@ -58,6 +58,9 @@ int main(int argc, char** argv) {
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);

View File

@ -93,6 +93,9 @@ int main(int argc, char** argv) {
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;