[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [RFC 10/10] tcg: switch on multithread.
From: |
fred . konrad |
Subject: |
[Qemu-devel] [RFC 10/10] tcg: switch on multithread. |
Date: |
Fri, 16 Jan 2015 18:19:57 +0100 |
From: KONRAD Frederic <address@hidden>
This switches on multithread.
Signed-off-by: KONRAD Frederic <address@hidden>
---
cpus.c | 85 +++++++++++++++++++++++-------------------------------------------
1 file changed, 30 insertions(+), 55 deletions(-)
diff --git a/cpus.c b/cpus.c
index 8ae70c2..ab327dd 100644
--- a/cpus.c
+++ b/cpus.c
@@ -64,7 +64,6 @@
#endif /* CONFIG_LINUX */
-static CPUState *next_cpu;
int64_t max_delay;
int64_t max_advance;
@@ -799,8 +798,6 @@ static bool iothread_requesting_mutex;
static QemuThread io_thread;
-static QemuThread *tcg_cpu_thread;
-
/* cpu creation */
static QemuCond qemu_cpu_cond;
/* system init */
@@ -907,10 +904,12 @@ static void qemu_wait_io_event_common(CPUState *cpu)
static void qemu_tcg_wait_io_event(CPUState *cpu)
{
- while (all_cpu_threads_idle()) {
+ while (cpu_thread_is_idle(cpu)) {
/* Start accounting real time to the virtual clock if the CPUs
are idle. */
- qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+ if ((all_cpu_threads_idle()) && (cpu->cpu_index == 0)) {
+ qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
+ }
qemu_cond_wait(cpu->halt_cond, &qemu_global_mutex);
}
@@ -918,9 +917,7 @@ static void qemu_tcg_wait_io_event(CPUState *cpu)
qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
}
- CPU_FOREACH(cpu) {
- qemu_wait_io_event_common(cpu);
- }
+ qemu_wait_io_event_common(cpu);
}
static void qemu_kvm_wait_io_event(CPUState *cpu)
@@ -1012,7 +1009,7 @@ static void *qemu_dummy_cpu_thread_fn(void *arg)
#endif
}
-static void tcg_exec_all(void);
+static void tcg_exec_all(CPUState *cpu);
static void *qemu_tcg_cpu_thread_fn(void *arg)
{
@@ -1022,34 +1019,26 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
qemu_thread_get_self(cpu->thread);
qemu_mutex_lock_iothread();
- CPU_FOREACH(cpu) {
- cpu->thread_id = qemu_get_thread_id();
- cpu->created = true;
- cpu->can_do_io = 1;
- }
- qemu_cond_signal(&qemu_cpu_cond);
-
- /* wait for initial kick-off after machine start */
- while (QTAILQ_FIRST(&cpus)->stopped) {
- qemu_cond_wait(QTAILQ_FIRST(&cpus)->halt_cond, &qemu_global_mutex);
+ cpu->thread_id = qemu_get_thread_id();
+ cpu->created = true;
+ cpu->can_do_io = 1;
- /* process any pending work */
- CPU_FOREACH(cpu) {
- qemu_wait_io_event_common(cpu);
- }
- }
+ qemu_cond_signal(&qemu_cpu_cond);
while (1) {
- tcg_exec_all();
+ if (!cpu->stopped) {
+ tcg_exec_all(cpu);
- if (use_icount) {
- int64_t deadline = qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
+ if (use_icount) {
+ int64_t deadline =
+ qemu_clock_deadline_ns_all(QEMU_CLOCK_VIRTUAL);
- if (deadline == 0) {
- qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ if (deadline == 0) {
+ qemu_clock_notify(QEMU_CLOCK_VIRTUAL);
+ }
}
}
- qemu_tcg_wait_io_event(QTAILQ_FIRST(&cpus));
+ qemu_tcg_wait_io_event(cpu);
}
return NULL;
@@ -1207,23 +1196,15 @@ static void qemu_tcg_init_vcpu(CPUState *cpu)
cpu->halt_cond = g_malloc0(sizeof(QemuCond));
qemu_cond_init(cpu->halt_cond);
-
- /* share a single thread for all cpus with TCG */
- if (!tcg_cpu_thread) {
- cpu->thread = g_malloc0(sizeof(QemuThread));
- snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG",
- cpu->cpu_index);
- qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn,
- cpu, QEMU_THREAD_JOINABLE);
+ cpu->thread = g_malloc0(sizeof(QemuThread));
+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/TCG", cpu->cpu_index);
+ qemu_thread_create(cpu->thread, thread_name, qemu_tcg_cpu_thread_fn, cpu,
+ QEMU_THREAD_JOINABLE);
#ifdef _WIN32
- cpu->hThread = qemu_thread_get_handle(cpu->thread);
+ 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;
+ while (!cpu->created) {
+ qemu_cond_wait(&qemu_cpu_cond, &qemu_global_mutex);
}
}
@@ -1370,21 +1351,15 @@ static int tcg_cpu_exec(CPUArchState *env)
return ret;
}
-static void tcg_exec_all(void)
+static void tcg_exec_all(CPUState *cpu)
{
int r;
+ CPUArchState *env = cpu->env_ptr;
/* Account partial waits to QEMU_CLOCK_VIRTUAL. */
qemu_clock_warp(QEMU_CLOCK_VIRTUAL);
- if (next_cpu == NULL) {
- next_cpu = first_cpu;
- }
- for (; next_cpu != NULL && !first_cpu->exit_loop_request;
- next_cpu = CPU_NEXT(next_cpu)) {
- CPUState *cpu = next_cpu;
- CPUArchState *env = cpu->env_ptr;
-
+ while (!cpu->exit_request) {
qemu_clock_enable(QEMU_CLOCK_VIRTUAL,
(cpu->singlestep_enabled & SSTEP_NOTIMER) == 0);
@@ -1399,7 +1374,7 @@ static void tcg_exec_all(void)
}
}
- first_cpu->exit_loop_request = 0;
+ cpu->exit_loop_request = 0;
}
void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
--
1.9.0
- Re: [Qemu-devel] [RFC 03/10] replace spinlock by QemuMutex., (continued)
- [Qemu-devel] [RFC 07/10] tcg: remove tcg_halt_cond global variable., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 08/10] Drop global lock during TCG code execution, fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 01/10] target-arm: protect cpu_exclusive_*., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 09/10] cpu: remove exit_request global., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 05/10] extract TBContext from TCGContext., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 10/10] tcg: switch on multithread.,
fred . konrad <=
- [Qemu-devel] [RFC 02/10] use a different translation block list for each cpu., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 06/10] protect TBContext with tb_lock., fred . konrad, 2015/01/16
- [Qemu-devel] [RFC 04/10] remove unused spinlock., fred . konrad, 2015/01/16