static void *qemu_tcg_cpu_thread_fn(void *arg) { CPUArchState *env = arg; qemu_tcg_init_cpu_signals(); qemu_thread_get_self(env->thread); /* signal CPU creation */ qemu_mutex_lock(&qemu_global_mutex); for (env = first_cpu; env != NULL; env = env->next_cpu) { env->thread_id = qemu_get_thread_id(); env->created = 1; } qemu_cond_signal(&qemu_cpu_cond); /* wait for initial kick-off after machine start */ while (first_cpu->stopped) { qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); /* process any pending work */ for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(env); } } while (1) { tcg_exec_all(); if (use_icount && qemu_clock_deadline(vm_clock) <= 0) { qemu_notify_event(); } qemu_tcg_wait_io_event(); } return NULL; }
static void qemu_tcg_wait_io_event(void) { CPUArchState *env; while (all_cpu_threads_idle()) { #ifdef CONFIG_S2E_DEBUG s2e_debug_print("CPU: qemu_tcg_wait_io_event: waiting for awaken cpu %p\n", tcg_halt_cond); #endif /* Start accounting real time to the virtual clock if the CPUs are idle. */ qemu_clock_warp(vm_clock); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); } while (iothread_requesting_mutex) { #ifdef CONFIG_S2E_DEBUG s2e_debug_print("CPU: qemu_tcg_wait_io_event iothread_requesting_mutex\n"); #endif qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex); } for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(env); } }
static void qemu_tcg_wait_io_event(void) { CPUState *env; while (all_cpu_threads_idle()) { /* Start accounting real time to the virtual clock if the CPUs are idle. */ qemu_clock_warp(vm_clock); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); } qemu_mutex_unlock(&qemu_global_mutex); /* * Users of qemu_global_mutex can be starved, having no chance * to acquire it since this path will get to it first. * So use another lock to provide fairness. */ qemu_mutex_lock(&qemu_fair_mutex); qemu_mutex_unlock(&qemu_fair_mutex); qemu_mutex_lock(&qemu_global_mutex); for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(env); } }
static void qemu_kvm_wait_io_event(CPUState *env) { while (!cpu_has_work(env)) qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000); qemu_kvm_eat_signal(env, 0); qemu_wait_io_event_common(env); }
static void qemu_kvm_wait_io_event(CPUState *env) { while (cpu_thread_is_idle(env)) { qemu_cond_wait(env->halt_cond, &qemu_global_mutex); } qemu_kvm_eat_signals(env); qemu_wait_io_event_common(env); }
static void qemu_kvm_wait_io_event(CPUArchState *env) { CPUState *cpu = ENV_GET_CPU(env); while (cpu_thread_is_idle(env)) { qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex); } qemu_kvm_eat_signals(env); qemu_wait_io_event_common(cpu); }
static void qemu_wait_io_event(CPUState *env) { while (!tcg_has_work()) qemu_cond_timedwait(env->halt_cond, &qemu_global_mutex, 1000); qemu_mutex_unlock(&qemu_global_mutex); /* * Users of qemu_global_mutex can be starved, having no chance * to acquire it since this path will get to it first. * So use another lock to provide fairness. */ qemu_mutex_lock(&qemu_fair_mutex); qemu_mutex_unlock(&qemu_fair_mutex); qemu_mutex_lock(&qemu_global_mutex); qemu_wait_io_event_common(env); }
static void qemu_tcg_wait_io_event(void) { CPUArchState *env; while (all_cpu_threads_idle()) { /* Start accounting real time to the virtual clock if the CPUs are idle. */ qemu_clock_warp(vm_clock); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); } while (iothread_requesting_mutex) { qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex); } for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(ENV_GET_CPU(env)); } }
static void qemu_tcg_wait_io_event(void) { CPUState *cpu; while (all_cpu_threads_idle()) { /* Start accounting real time to the virtual clock if the CPUs are idle. */ qemu_clock_warp(QEMU_CLOCK_VIRTUAL); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); } while (iothread_requesting_mutex) { qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex); } for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { qemu_wait_io_event_common(cpu); } }
static void *qemu_dummy_cpu_thread_fn(void *arg) { #ifdef _WIN32 fprintf(stderr, "qtest is not supported under Windows\n"); exit(1); #else CPUArchState *env = arg; CPUState *cpu = ENV_GET_CPU(env); sigset_t waitset; int r; qemu_mutex_lock_iothread(); qemu_thread_get_self(cpu->thread); cpu->thread_id = qemu_get_thread_id(); sigemptyset(&waitset); sigaddset(&waitset, SIG_IPI); /* signal CPU creation */ cpu->created = true; qemu_cond_signal(&qemu_cpu_cond); cpu_single_env = env; while (1) { cpu_single_env = NULL; qemu_mutex_unlock_iothread(); do { int sig; r = sigwait(&waitset, &sig); } while (r == -1 && (errno == EAGAIN || errno == EINTR)); if (r == -1) { perror("sigwait"); exit(1); } qemu_mutex_lock_iothread(); cpu_single_env = env; qemu_wait_io_event_common(cpu); } return NULL; #endif }
static void qemu_tcg_wait_io_event(void) { CPUState *env; while (!any_cpu_has_work()) qemu_cond_timedwait(tcg_halt_cond, &qemu_global_mutex, 1000); qemu_mutex_unlock(&qemu_global_mutex); /* * Users of qemu_global_mutex can be starved, having no chance * to acquire it since this path will get to it first. * So use another lock to provide fairness. */ qemu_mutex_lock(&qemu_fair_mutex); qemu_mutex_unlock(&qemu_fair_mutex); qemu_mutex_lock(&qemu_global_mutex); for (env = first_cpu; env != NULL; env = env->next_cpu) { qemu_wait_io_event_common(env); } }
static void *qemu_tcg_cpu_thread_fn(void *arg) { CPUState *cpu = arg; qemu_tcg_init_cpu_signals(); qemu_thread_get_self(cpu->thread); qemu_mutex_lock(&qemu_global_mutex); qemu_for_each_cpu(tcg_signal_cpu_creation, NULL); qemu_cond_signal(&qemu_cpu_cond); /* wait for initial kick-off after machine start */ while (first_cpu->stopped) { qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); /* process any pending work */ for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { qemu_wait_io_event_common(cpu); } } while (1) { tcg_exec_all(); if (use_icount) { int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL); if (deadline == 0) { qemu_clock_notify(QEMU_CLOCK_VIRTUAL); } } qemu_tcg_wait_io_event(); } return NULL; }