Move per-cpu thread information to CPUState. Initialize through per-arch cpu_init. Signed-off-by: Marcelo Tosatti Index: trunk/cpu-defs.h =================================================================== --- trunk.orig/cpu-defs.h +++ trunk/cpu-defs.h @@ -158,6 +158,8 @@ typedef struct CPUWatchpoint { TAILQ_ENTRY(CPUWatchpoint) entry; } CPUWatchpoint; +#include "qemu-thread.h" + #define CPU_TEMP_BUF_NLONGS 128 #define CPU_COMMON \ struct TranslationBlock *current_tb; /* currently executing TB */ \ @@ -209,6 +211,9 @@ typedef struct CPUWatchpoint { /* user data */ \ void *opaque; \ \ + uint32_t created; \ + struct QemuThread *thread; \ + struct QemuCond *halt_cond; \ const char *cpu_model_str; \ struct KVMState *kvm_state; \ struct kvm_run *kvm_run; \ Index: trunk/target-i386/helper.c =================================================================== --- trunk.orig/target-i386/helper.c +++ trunk/target-i386/helper.c @@ -1670,5 +1670,8 @@ CPUX86State *cpu_x86_init(const char *cp #endif if (kvm_enabled()) kvm_init_vcpu(env); + + qemu_init_vcpu(env); + return env; } Index: trunk/vl.c =================================================================== --- trunk.orig/vl.c +++ trunk/vl.c @@ -282,8 +282,15 @@ QemuMutex qemu_global_mutex; QemuMutex qemu_fair_mutex; QemuThread io_thread; -QemuThread cpus_thread; -QemuCond halt_cond; + +QemuThread *tcg_cpu_thread; +QemuCond *tcg_halt_cond; + +static int qemu_system_ready; +/* cpu creation */ +QemuCond qemu_cpu_cond; +/* system init */ +QemuCond qemu_system_cond; /***********************************************************/ /* x86 ISA bus support */ @@ -3751,7 +3758,7 @@ static void qemu_wait_io_event(CPUState { if (timeout) while (!tcg_has_work(env)) - qemu_cond_timedwait(&halt_cond, &qemu_global_mutex, timeout); + qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, timeout); qemu_mutex_unlock(&qemu_global_mutex); @@ -3766,9 +3773,10 @@ static void qemu_wait_io_event(CPUState qemu_mutex_lock(&qemu_global_mutex); } -void qemu_cpu_kick(void *env) +void qemu_cpu_kick(void *_env) { - qemu_cond_broadcast(&halt_cond); + CPUState *env = _env; + qemu_cond_broadcast(env->halt_cond); } int qemu_cpu_self(void *env) @@ -3822,7 +3830,7 @@ static void qemu_signal_lock(unsigned in qemu_mutex_lock(&qemu_fair_mutex); while (qemu_mutex_trylock(&qemu_global_mutex)) { - qemu_thread_signal(&cpus_thread, SIGUSR1); + qemu_thread_signal(tcg_cpu_thread, SIGUSR1); if (!qemu_mutex_timedlock(&qemu_global_mutex, msecs)) break; } @@ -3951,12 +3959,19 @@ static void *cpu_main_loop(void *arg) #ifdef CONFIG_PROFILER int64_t ti; #endif - CPUState *env; + CPUState *env = arg; block_io_signals(); - qemu_thread_self(&cpus_thread); + qemu_thread_self(env->thread); + /* signal CPU creation */ qemu_mutex_lock(&qemu_global_mutex); + env->created = 1; + qemu_cond_signal(&qemu_cpu_cond); + + /* and wait for machine initialization */ + while (!qemu_system_ready) + qemu_cond_timedwait(&qemu_system_cond, &qemu_global_mutex, 100); cur_cpu = env = first_cpu; next_cpu = cur_cpu->next_cpu ?: first_cpu; @@ -4100,19 +4115,41 @@ static void *cpu_main_loop(void *arg) return NULL; } -static void main_loop(void) +void qemu_init_vcpu(void *_env) +{ + CPUState *env = _env; + /* share a single thread for all cpus with TCG */ + if (!tcg_cpu_thread) { + env->thread = qemu_mallocz(sizeof(QemuThread)); + env->halt_cond = qemu_mallocz(sizeof(QemuCond)); + qemu_cond_init(env->halt_cond); + qemu_thread_create(env->thread, cpu_main_loop, env); + while (env->created == 0) + qemu_cond_timedwait(&qemu_cpu_cond, &qemu_global_mutex, 100); + tcg_cpu_thread = env->thread; + tcg_halt_cond = env->halt_cond; + } else { + env->thread = tcg_cpu_thread; + env->halt_cond = tcg_halt_cond; + } +} + +static void qemu_init_state(void) { - qemu_cond_init(&halt_cond); qemu_mutex_init(&qemu_fair_mutex); qemu_mutex_init(&qemu_global_mutex); qemu_mutex_lock(&qemu_global_mutex); +} +static void main_loop(void) +{ qemu_thread_self(&io_thread); setup_iothread_fd(); unblock_io_signals(); - qemu_thread_create(&cpus_thread, cpu_main_loop, NULL); + qemu_system_ready = 1; + qemu_cond_broadcast(&qemu_system_cond); while (1) main_loop_wait(1000); @@ -5578,6 +5615,7 @@ int main(int argc, char **argv, char **e if (smp_cpus > 1) kqemu_allowed = 0; #endif + qemu_init_state(); linux_boot = (kernel_filename != NULL); net_boot = (boot_devices_bitmap >> ('n' - 'a')) & 0xF; Index: trunk/qemu-common.h =================================================================== --- trunk.orig/qemu-common.h +++ trunk/qemu-common.h @@ -195,6 +195,12 @@ void qemu_notify_event(void); void qemu_cpu_kick(void *env); int qemu_cpu_self(void *env); +#ifdef CONFIG_USER_ONLY +#define qemu_init_vcpu(env) do { } while (0) +#else +void qemu_init_vcpu(void *env); +#endif + typedef struct QEMUIOVector { struct iovec *iov; int niov; Index: trunk/target-arm/helper.c =================================================================== --- trunk.orig/target-arm/helper.c +++ trunk/target-arm/helper.c @@ -267,6 +267,7 @@ CPUARMState *cpu_arm_init(const char *cp gdb_register_coprocessor(env, vfp_gdb_get_reg, vfp_gdb_set_reg, 19, "arm-vfp.xml", 0); } + qemu_init_vcpu(env); return env; } Index: trunk/target-m68k/helper.c =================================================================== --- trunk.orig/target-m68k/helper.c +++ trunk/target-m68k/helper.c @@ -180,6 +180,7 @@ CPUM68KState *cpu_m68k_init(const char * } cpu_reset(env); + qemu_init_vcpu(env); return env; } Index: trunk/target-ppc/helper.c =================================================================== --- trunk.orig/target-ppc/helper.c +++ trunk/target-ppc/helper.c @@ -2831,6 +2831,7 @@ CPUPPCState *cpu_ppc_init (const char *c if (kvm_enabled()) kvm_init_vcpu(env); + qemu_init_vcpu(env); return env; } Index: trunk/target-sparc/helper.c =================================================================== --- trunk.orig/target-sparc/helper.c +++ trunk/target-sparc/helper.c @@ -723,6 +723,7 @@ CPUSPARCState *cpu_sparc_init(const char return NULL; } cpu_reset(env); + qemu_init_vcpu(env); return env; } Index: trunk/target-alpha/translate.c =================================================================== --- trunk.orig/target-alpha/translate.c +++ trunk/target-alpha/translate.c @@ -2495,6 +2495,7 @@ CPUAlphaState * cpu_alpha_init (const ch env->ipr[IPR_SISR] = 0; env->ipr[IPR_VIRBND] = -1ULL; + qemu_init_vcpu(env); return env; } Index: trunk/target-cris/translate.c =================================================================== --- trunk.orig/target-cris/translate.c +++ trunk/target-cris/translate.c @@ -3404,6 +3404,7 @@ CPUCRISState *cpu_cris_init (const char cpu_exec_init(env); cpu_reset(env); + qemu_init_vcpu(env); if (tcg_initialized) return env; Index: trunk/target-mips/translate.c =================================================================== --- trunk.orig/target-mips/translate.c +++ trunk/target-mips/translate.c @@ -8480,6 +8480,7 @@ CPUMIPSState *cpu_mips_init (const char env->cpu_model_str = cpu_model; mips_tcg_init(); cpu_reset(env); + qemu_init_vcpu(env); return env; } Index: trunk/target-sh4/translate.c =================================================================== --- trunk.orig/target-sh4/translate.c +++ trunk/target-sh4/translate.c @@ -288,6 +288,7 @@ CPUSH4State *cpu_sh4_init(const char *cp cpu_sh4_reset(env); cpu_sh4_register(env, def); tlb_flush(env, 1); + qemu_init_vcpu(env); return env; }