static void qemu_tcg_init_vcpu(void *_env) { CPUArchState *env = _env; /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { #ifdef CONFIG_S2E /* Forks inherit parent's memory, therefore we do not want to allocate new memory regions, just overwrite them. */ if (!s2e_is_forking()) { env->thread = g_malloc0(sizeof(QemuThread)); env->halt_cond = g_malloc0(sizeof(QemuCond)); } #else env->thread = g_malloc0(sizeof(QemuThread)); env->halt_cond = g_malloc0(sizeof(QemuCond)); #endif qemu_cond_init(env->halt_cond); tcg_halt_cond = env->halt_cond; qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env, QEMU_THREAD_JOINABLE); #ifdef _WIN32 env->hThread = qemu_thread_get_handle(env->thread); #endif while (env->created == 0) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } tcg_cpu_thread = env->thread; } else { env->thread = tcg_cpu_thread; env->halt_cond = tcg_halt_cond; } }
void *qemu_thread_join(QemuThread *thread) { QemuThreadData *data; void *ret; HANDLE handle; data = thread->data; if (!data) { return NULL; } /* * Because multiple copies of the QemuThread can exist via * qemu_thread_get_self, we need to store a value that cannot * leak there. The simplest, non racy way is to store the TID, * discard the handle that _beginthreadex gives back, and * get another copy of the handle here. */ handle = qemu_thread_get_handle(thread); if (handle) { WaitForSingleObject(handle, INFINITE); CloseHandle(handle); } ret = data->ret; assert(data->mode != QEMU_THREAD_DETACHED); DeleteCriticalSection(&data->cs); g_free(data); return ret; }
static void qemu_tcg_init_vcpu(CPUState *cpu) { /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { cpu->thread = g_malloc0(sizeof(QemuThread)); cpu->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(cpu->halt_cond); tcg_halt_cond = cpu->halt_cond; qemu_thread_create(cpu->thread, qemu_tcg_cpu_thread_fn, cpu, QEMU_THREAD_JOINABLE); #ifdef _WIN32 cpu->hThread = qemu_thread_get_handle(cpu->thread); #endif while (!cpu->created) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } tcg_cpu_thread = cpu->thread; } else { cpu->thread = tcg_cpu_thread; cpu->halt_cond = tcg_halt_cond; } }
static void qemu_tcg_init_vcpu(void *_env) { CPUArchState *env = _env; /* share a single thread for all cpus with TCG */ if (!tcg_cpu_thread) { env->thread = g_malloc0(sizeof(QemuThread)); env->halt_cond = g_malloc0(sizeof(QemuCond)); qemu_cond_init(env->halt_cond); tcg_halt_cond = env->halt_cond; qemu_thread_create(env->thread, qemu_tcg_cpu_thread_fn, env, QEMU_THREAD_JOINABLE); #ifdef _WIN32 env->hThread = qemu_thread_get_handle(env->thread); #endif while (env->created == 0) { qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex); } tcg_cpu_thread = env->thread; } else { env->thread = tcg_cpu_thread; env->halt_cond = tcg_halt_cond; } }