diff --git a/include/tcg/tcg.h b/include/tcg/tcg.h index e63450a893..8081484b4a 100644 --- a/include/tcg/tcg.h +++ b/include/tcg/tcg.h @@ -851,6 +851,10 @@ static inline void *tcg_malloc(int size) } } +#ifdef XBOX +void tcg_register_init_ctx(void); +#endif + void tcg_context_init(TCGContext *s); void tcg_register_thread(void); void tcg_prologue_init(TCGContext *s); diff --git a/tcg/tcg.c b/tcg/tcg.c index 1362bc6101..bc17c2ea0d 100644 --- a/tcg/tcg.c +++ b/tcg/tcg.c @@ -775,6 +775,21 @@ void tcg_register_thread(void) tcg_ctx = &tcg_init_ctx; } #else + +#ifdef XBOX +void tcg_register_init_ctx(void) +{ + /* + * For xemu we may exercise functions on the UI thread that would otherwise + * run on the main thread following initialization. We retain the BQL when + * running such commands, which should make this safe, but there are some + * data stored in TLS which get initialized early on and may be required + * later. + */ + tcg_ctx = &tcg_init_ctx; +} +#endif + void tcg_register_thread(void) { MachineState *ms = MACHINE(qdev_get_machine()); diff --git a/ui/xemu.c b/ui/xemu.c index 095b15de9c..b7a3ba50d1 100644 --- a/ui/xemu.c +++ b/ui/xemu.c @@ -31,6 +31,7 @@ #include "qemu/module.h" #include "qemu/thread.h" #include "qemu/main-loop.h" +#include "qemu/rcu.h" #include "qemu-version.h" #include "qemu-common.h" #include "qapi/error.h" @@ -49,6 +50,8 @@ #include "hw/xbox/smbus.h" // For eject, drive tray #include "hw/xbox/nv2a/nv2a.h" +void tcg_register_init_ctx(void); // tcg.c + // #define DEBUG_XEMU_C #ifdef DEBUG_XEMU_C @@ -1451,11 +1454,20 @@ int main(int argc, char **argv) DPRINTF("Main thread: waiting for display_init_sem\n"); qemu_sem_wait(&display_init_sem); + /* + * FIXME: May want to create a callback mechanism for main QEMU thread + * to just run functions to avoid TLS bugs and locking issues. + */ + tcg_register_init_ctx(); + rcu_register_thread(); + DPRINTF("Main thread: initializing app\n"); while (1) { sdl2_gl_refresh(&sdl2_console[0].dcl); } + + rcu_unregister_thread(); } void xemu_eject_disc(void)