Lines Matching +full:single +full:- +full:cpu
2 * QEMU TCG Single Threaded vCPUs implementation
4 * Copyright (c) 2003-2008 Fabrice Bellard
30 #include "sysemu/cpu-timers.h"
31 #include "qemu/main-loop.h"
33 #include "qemu/guest-random.h"
34 #include "exec/exec-all.h"
36 #include "tcg-accel-ops.h"
37 #include "tcg-accel-ops-rr.h"
38 #include "tcg-accel-ops-icount.h"
43 CPUState *cpu; in rr_kick_vcpu_thread() local
45 CPU_FOREACH(cpu) { in rr_kick_vcpu_thread()
46 cpu_exit(cpu); in rr_kick_vcpu_thread()
53 * The kick timer is responsible for moving single threaded vCPU
55 * timer event we force a cpu->exit so the next vCPU can get
70 /* Kick the currently round-robin scheduled vCPU to next */
73 CPUState *cpu; in rr_kick_next_cpu() local
75 cpu = qatomic_read(&rr_current_cpu); in rr_kick_next_cpu()
76 if (cpu) { in rr_kick_next_cpu()
77 cpu_exit(cpu); in rr_kick_next_cpu()
79 /* Finish kicking this cpu before reading again. */ in rr_kick_next_cpu()
81 } while (cpu != qatomic_read(&rr_current_cpu)); in rr_kick_next_cpu()
110 CPUState *cpu; in rr_wait_io_event() local
114 qemu_cond_wait_bql(first_cpu->halt_cond); in rr_wait_io_event()
119 CPU_FOREACH(cpu) { in rr_wait_io_event()
120 qemu_wait_io_event_common(cpu); in rr_wait_io_event()
130 CPUState *cpu; in rr_deal_with_unplugged_cpus() local
132 CPU_FOREACH(cpu) { in rr_deal_with_unplugged_cpus()
133 if (cpu->unplug && !cpu_can_run(cpu)) { in rr_deal_with_unplugged_cpus()
134 tcg_cpu_destroy(cpu); in rr_deal_with_unplugged_cpus()
146 * Calculate the number of CPUs that we will process in a single iteration of
147 * the main CPU thread loop so that we can fairly distribute the instruction
150 * The CPU count is cached based on the CPU list generation ID to avoid
157 CPUState *cpu; in rr_cpu_count() local
163 CPU_FOREACH(cpu) { in rr_cpu_count()
173 * In the single-threaded case each vCPU is simulated in turn. If
174 * there is more than a single vCPU we create a simple timer to kick
176 * This is done explicitly rather than relying on side-effects
183 CPUState *cpu = arg; in rr_cpu_thread_fn() local
192 qemu_thread_get_self(cpu->thread); in rr_cpu_thread_fn()
194 cpu->thread_id = qemu_get_thread_id(); in rr_cpu_thread_fn()
195 cpu->neg.can_do_io = true; in rr_cpu_thread_fn()
196 cpu_thread_signal_created(cpu); in rr_cpu_thread_fn()
197 qemu_guest_random_seed_thread_part2(cpu->random_seed); in rr_cpu_thread_fn()
199 /* wait for initial kick-off after machine start */ in rr_cpu_thread_fn()
200 while (first_cpu->stopped) { in rr_cpu_thread_fn()
201 qemu_cond_wait_bql(first_cpu->halt_cond); in rr_cpu_thread_fn()
204 CPU_FOREACH(cpu) { in rr_cpu_thread_fn()
205 current_cpu = cpu; in rr_cpu_thread_fn()
206 qemu_wait_io_event_common(cpu); in rr_cpu_thread_fn()
212 cpu = first_cpu; in rr_cpu_thread_fn()
215 cpu->exit_request = 1; in rr_cpu_thread_fn()
241 if (!cpu) { in rr_cpu_thread_fn()
242 cpu = first_cpu; in rr_cpu_thread_fn()
245 while (cpu && cpu_work_list_empty(cpu) && !cpu->exit_request) { in rr_cpu_thread_fn()
247 qatomic_set_mb(&rr_current_cpu, cpu); in rr_cpu_thread_fn()
249 current_cpu = cpu; in rr_cpu_thread_fn()
252 (cpu->singlestep_enabled & SSTEP_NOTIMER) == 0); in rr_cpu_thread_fn()
254 if (cpu_can_run(cpu)) { in rr_cpu_thread_fn()
259 icount_prepare_for_run(cpu, cpu_budget); in rr_cpu_thread_fn()
261 r = tcg_cpu_exec(cpu); in rr_cpu_thread_fn()
263 icount_process_data(cpu); in rr_cpu_thread_fn()
268 cpu_handle_guest_debug(cpu); in rr_cpu_thread_fn()
272 cpu_exec_step_atomic(cpu); in rr_cpu_thread_fn()
276 } else if (cpu->stop) { in rr_cpu_thread_fn()
277 if (cpu->unplug) { in rr_cpu_thread_fn()
278 cpu = CPU_NEXT(cpu); in rr_cpu_thread_fn()
283 cpu = CPU_NEXT(cpu); in rr_cpu_thread_fn()
284 } /* while (cpu && !cpu->exit_request).. */ in rr_cpu_thread_fn()
289 if (cpu && cpu->exit_request) { in rr_cpu_thread_fn()
290 qatomic_set_mb(&cpu->exit_request, 0); in rr_cpu_thread_fn()
308 void rr_start_vcpu_thread(CPUState *cpu) in rr_start_vcpu_thread() argument
315 tcg_cpu_init_cflags(cpu, false); in rr_start_vcpu_thread()
318 single_tcg_halt_cond = cpu->halt_cond; in rr_start_vcpu_thread()
319 single_tcg_cpu_thread = cpu->thread; in rr_start_vcpu_thread()
321 /* share a single thread for all cpus with TCG */ in rr_start_vcpu_thread()
323 qemu_thread_create(cpu->thread, thread_name, in rr_start_vcpu_thread()
325 cpu, QEMU_THREAD_JOINABLE); in rr_start_vcpu_thread()
328 g_free(cpu->thread); in rr_start_vcpu_thread()
329 qemu_cond_destroy(cpu->halt_cond); in rr_start_vcpu_thread()
330 g_free(cpu->halt_cond); in rr_start_vcpu_thread()
331 cpu->thread = single_tcg_cpu_thread; in rr_start_vcpu_thread()
332 cpu->halt_cond = single_tcg_halt_cond; in rr_start_vcpu_thread()
335 cpu->thread_id = first_cpu->thread_id; in rr_start_vcpu_thread()
336 cpu->neg.can_do_io = 1; in rr_start_vcpu_thread()
337 cpu->created = true; in rr_start_vcpu_thread()