src/gba/gba-thread.c (view raw)
1#include "gba-thread.h"
2
3#include "arm.h"
4#include "debugger.h"
5#include "gba.h"
6
7#include <signal.h>
8
9static void* _GBAThreadRun(void* context) {
10 struct ARMDebugger debugger;
11 struct GBA gba;
12 struct GBAThread* threadContext = context;
13
14 sigset_t signals;
15 sigfillset(&signals);
16 pthread_sigmask(SIG_UNBLOCK, &signals, 0);
17
18 GBAInit(&gba);
19 if (threadContext->renderer) {
20 GBAVideoAssociateRenderer(&gba.video, threadContext->renderer);
21 }
22
23 threadContext->gba = &gba;
24 if (threadContext->fd >= 0) {
25 GBALoadROM(&gba, threadContext->fd);
26 }
27 if (threadContext->useDebugger) {
28 threadContext->debugger = &debugger;
29 GBAAttachDebugger(&gba, &debugger);
30 } else {
31 threadContext->debugger = 0;
32 }
33 gba.keySource = &threadContext->activeKeys;
34
35 threadContext->started = 1;
36 pthread_mutex_lock(&threadContext->mutex);
37 pthread_cond_broadcast(&threadContext->cond);
38 pthread_mutex_unlock(&threadContext->mutex);
39
40 if (threadContext->useDebugger) {
41 ARMDebuggerRun(&debugger);
42 threadContext->started = 0;
43 } else {
44 while (threadContext->started) {
45 ARMRun(&gba.cpu);
46 }
47 }
48 GBADeinit(&gba);
49
50 return 0;
51}
52
53int GBAThreadStart(struct GBAThread* threadContext) {
54 // TODO: error check
55 {
56 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
57 threadContext->mutex = mutex;
58 pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
59 threadContext->cond = cond;
60 }
61 pthread_mutex_init(&threadContext->mutex, 0);
62 pthread_cond_init(&threadContext->cond, 0);
63
64 pthread_mutex_lock(&threadContext->mutex);
65 threadContext->activeKeys = 0;
66 threadContext->started = 0;
67 pthread_create(&threadContext->thread, 0, _GBAThreadRun, threadContext);
68 pthread_cond_wait(&threadContext->cond, &threadContext->mutex);
69 pthread_mutex_unlock(&threadContext->mutex);
70
71 return 0;
72}
73
74void GBAThreadJoin(struct GBAThread* threadContext) {
75 pthread_join(threadContext->thread, 0);
76
77 pthread_mutex_destroy(&threadContext->mutex);
78 pthread_cond_destroy(&threadContext->cond);
79}