cpu: Use QTAILQ for CPU list

Introduce CPU_FOREACH(), CPU_FOREACH_SAFE() and CPU_NEXT() shorthand
macros.

Signed-off-by: Andreas Färber <afaerber@suse.de>
This commit is contained in:
Andreas Färber 2013-06-24 23:50:24 +02:00
parent 27013bf20d
commit bdc44640cb
26 changed files with 94 additions and 112 deletions

49
cpus.c
View File

@ -86,7 +86,7 @@ static bool all_cpu_threads_idle(void)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (!cpu_thread_is_idle(cpu)) { if (!cpu_thread_is_idle(cpu)) {
return false; return false;
} }
@ -416,7 +416,7 @@ void hw_error(const char *fmt, ...)
fprintf(stderr, "qemu: hardware error: "); fprintf(stderr, "qemu: hardware error: ");
vfprintf(stderr, fmt, ap); vfprintf(stderr, fmt, ap);
fprintf(stderr, "\n"); fprintf(stderr, "\n");
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
fprintf(stderr, "CPU #%d:\n", cpu->cpu_index); fprintf(stderr, "CPU #%d:\n", cpu->cpu_index);
cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU); cpu_dump_state(cpu, stderr, fprintf, CPU_DUMP_FPU);
} }
@ -428,7 +428,7 @@ void cpu_synchronize_all_states(void)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
cpu_synchronize_state(cpu); cpu_synchronize_state(cpu);
} }
} }
@ -437,7 +437,7 @@ void cpu_synchronize_all_post_reset(void)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
cpu_synchronize_post_reset(cpu); cpu_synchronize_post_reset(cpu);
} }
} }
@ -446,7 +446,7 @@ void cpu_synchronize_all_post_init(void)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
cpu_synchronize_post_init(cpu); cpu_synchronize_post_init(cpu);
} }
} }
@ -760,7 +760,7 @@ static void qemu_tcg_wait_io_event(void)
qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex); qemu_cond_wait(&qemu_io_proceeded_cond, &qemu_global_mutex);
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
qemu_wait_io_event_common(cpu); qemu_wait_io_event_common(cpu);
} }
} }
@ -872,11 +872,11 @@ static void *qemu_tcg_cpu_thread_fn(void *arg)
qemu_cond_signal(&qemu_cpu_cond); qemu_cond_signal(&qemu_cpu_cond);
/* wait for initial kick-off after machine start */ /* wait for initial kick-off after machine start */
while (first_cpu->stopped) { while (QTAILQ_FIRST(&cpus)->stopped) {
qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex); qemu_cond_wait(tcg_halt_cond, &qemu_global_mutex);
/* process any pending work */ /* process any pending work */
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
qemu_wait_io_event_common(cpu); qemu_wait_io_event_common(cpu);
} }
} }
@ -991,13 +991,12 @@ void qemu_mutex_unlock_iothread(void)
static int all_vcpus_paused(void) static int all_vcpus_paused(void)
{ {
CPUState *cpu = first_cpu; CPUState *cpu;
while (cpu) { CPU_FOREACH(cpu) {
if (!cpu->stopped) { if (!cpu->stopped) {
return 0; return 0;
} }
cpu = cpu->next_cpu;
} }
return 1; return 1;
@ -1005,23 +1004,20 @@ static int all_vcpus_paused(void)
void pause_all_vcpus(void) void pause_all_vcpus(void)
{ {
CPUState *cpu = first_cpu; CPUState *cpu;
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false); qemu_clock_enable(QEMU_CLOCK_VIRTUAL, false);
while (cpu) { CPU_FOREACH(cpu) {
cpu->stop = true; cpu->stop = true;
qemu_cpu_kick(cpu); qemu_cpu_kick(cpu);
cpu = cpu->next_cpu;
} }
if (qemu_in_vcpu_thread()) { if (qemu_in_vcpu_thread()) {
cpu_stop_current(); cpu_stop_current();
if (!kvm_enabled()) { if (!kvm_enabled()) {
cpu = first_cpu; CPU_FOREACH(cpu) {
while (cpu) {
cpu->stop = false; cpu->stop = false;
cpu->stopped = true; cpu->stopped = true;
cpu = cpu->next_cpu;
} }
return; return;
} }
@ -1029,10 +1025,8 @@ void pause_all_vcpus(void)
while (!all_vcpus_paused()) { while (!all_vcpus_paused()) {
qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex); qemu_cond_wait(&qemu_pause_cond, &qemu_global_mutex);
cpu = first_cpu; CPU_FOREACH(cpu) {
while (cpu) {
qemu_cpu_kick(cpu); qemu_cpu_kick(cpu);
cpu = cpu->next_cpu;
} }
} }
} }
@ -1046,12 +1040,11 @@ void cpu_resume(CPUState *cpu)
void resume_all_vcpus(void) void resume_all_vcpus(void)
{ {
CPUState *cpu = first_cpu; CPUState *cpu;
qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true); qemu_clock_enable(QEMU_CLOCK_VIRTUAL, true);
while (cpu) { CPU_FOREACH(cpu) {
cpu_resume(cpu); cpu_resume(cpu);
cpu = cpu->next_cpu;
} }
} }
@ -1215,7 +1208,7 @@ static void tcg_exec_all(void)
if (next_cpu == NULL) { if (next_cpu == NULL) {
next_cpu = first_cpu; next_cpu = first_cpu;
} }
for (; next_cpu != NULL && !exit_request; next_cpu = next_cpu->next_cpu) { for (; next_cpu != NULL && !exit_request; next_cpu = CPU_NEXT(next_cpu)) {
CPUState *cpu = next_cpu; CPUState *cpu = next_cpu;
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
@ -1240,7 +1233,7 @@ void set_numa_modes(void)
CPUState *cpu; CPUState *cpu;
int i; int i;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
for (i = 0; i < nb_numa_nodes; i++) { for (i = 0; i < nb_numa_nodes; i++) {
if (test_bit(cpu->cpu_index, node_cpumask[i])) { if (test_bit(cpu->cpu_index, node_cpumask[i])) {
cpu->numa_node = i; cpu->numa_node = i;
@ -1262,7 +1255,7 @@ CpuInfoList *qmp_query_cpus(Error **errp)
CpuInfoList *head = NULL, *cur_item = NULL; CpuInfoList *head = NULL, *cur_item = NULL;
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
CpuInfoList *info; CpuInfoList *info;
#if defined(TARGET_I386) #if defined(TARGET_I386)
X86CPU *x86_cpu = X86_CPU(cpu); X86CPU *x86_cpu = X86_CPU(cpu);
@ -1391,7 +1384,7 @@ void qmp_inject_nmi(Error **errp)
#if defined(TARGET_I386) #if defined(TARGET_I386)
CPUState *cs; CPUState *cs;
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
X86CPU *cpu = X86_CPU(cs); X86CPU *cpu = X86_CPU(cs);
CPUX86State *env = &cpu->env; CPUX86State *env = &cpu->env;
@ -1405,7 +1398,7 @@ void qmp_inject_nmi(Error **errp)
CPUState *cs; CPUState *cs;
S390CPU *cpu; S390CPU *cpu;
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
cpu = S390_CPU(cs); cpu = S390_CPU(cs);
if (cpu->env.cpu_num == monitor_get_cpu_index()) { if (cpu->env.cpu_num == monitor_get_cpu_index()) {
if (s390_cpu_restart(S390_CPU(cs)) == -1) { if (s390_cpu_restart(S390_CPU(cs)) == -1) {

View File

@ -189,7 +189,7 @@ void cpu_tlb_reset_dirty_all(ram_addr_t start1, ram_addr_t length)
CPUState *cpu; CPUState *cpu;
CPUArchState *env; CPUArchState *env;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
int mmu_idx; int mmu_idx;
env = cpu->env_ptr; env = cpu->env_ptr;

10
dump.c
View File

@ -277,7 +277,7 @@ static int write_elf64_notes(DumpState *s)
int ret; int ret;
int id; int id;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
id = cpu_index(cpu); id = cpu_index(cpu);
ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s); ret = cpu_write_elf64_note(fd_write_vmcore, cpu, id, s);
if (ret < 0) { if (ret < 0) {
@ -286,7 +286,7 @@ static int write_elf64_notes(DumpState *s)
} }
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s); ret = cpu_write_elf64_qemunote(fd_write_vmcore, cpu, s);
if (ret < 0) { if (ret < 0) {
dump_error(s, "dump: failed to write CPU status.\n"); dump_error(s, "dump: failed to write CPU status.\n");
@ -327,7 +327,7 @@ static int write_elf32_notes(DumpState *s)
int ret; int ret;
int id; int id;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
id = cpu_index(cpu); id = cpu_index(cpu);
ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s); ret = cpu_write_elf32_note(fd_write_vmcore, cpu, id, s);
if (ret < 0) { if (ret < 0) {
@ -336,7 +336,7 @@ static int write_elf32_notes(DumpState *s)
} }
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s); ret = cpu_write_elf32_qemunote(fd_write_vmcore, cpu, s);
if (ret < 0) { if (ret < 0) {
dump_error(s, "dump: failed to write CPU status.\n"); dump_error(s, "dump: failed to write CPU status.\n");
@ -734,7 +734,7 @@ static int dump_init(DumpState *s, int fd, bool paging, bool has_filter,
*/ */
cpu_synchronize_all_states(); cpu_synchronize_all_states();
nr_cpus = 0; nr_cpus = 0;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
nr_cpus++; nr_cpus++;
} }

26
exec.c
View File

@ -69,7 +69,7 @@ static MemoryRegion io_mem_unassigned;
#endif #endif
CPUState *first_cpu; struct CPUTailQ cpus = QTAILQ_HEAD_INITIALIZER(cpus);
/* current CPU in the current thread. It is only valid inside /* current CPU in the current thread. It is only valid inside
cpu_exec() */ cpu_exec() */
DEFINE_TLS(CPUState *, current_cpu); DEFINE_TLS(CPUState *, current_cpu);
@ -351,26 +351,23 @@ const VMStateDescription vmstate_cpu_common = {
CPUState *qemu_get_cpu(int index) CPUState *qemu_get_cpu(int index)
{ {
CPUState *cpu = first_cpu; CPUState *cpu;
while (cpu) { CPU_FOREACH(cpu) {
if (cpu->cpu_index == index) { if (cpu->cpu_index == index) {
break; return cpu;
} }
cpu = cpu->next_cpu;
} }
return cpu; return NULL;
} }
void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data) void qemu_for_each_cpu(void (*func)(CPUState *cpu, void *data), void *data)
{ {
CPUState *cpu; CPUState *cpu;
cpu = first_cpu; CPU_FOREACH(cpu) {
while (cpu) {
func(cpu, data); func(cpu, data);
cpu = cpu->next_cpu;
} }
} }
@ -378,17 +375,14 @@ void cpu_exec_init(CPUArchState *env)
{ {
CPUState *cpu = ENV_GET_CPU(env); CPUState *cpu = ENV_GET_CPU(env);
CPUClass *cc = CPU_GET_CLASS(cpu); CPUClass *cc = CPU_GET_CLASS(cpu);
CPUState **pcpu; CPUState *some_cpu;
int cpu_index; int cpu_index;
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
cpu_list_lock(); cpu_list_lock();
#endif #endif
cpu->next_cpu = NULL;
pcpu = &first_cpu;
cpu_index = 0; cpu_index = 0;
while (*pcpu != NULL) { CPU_FOREACH(some_cpu) {
pcpu = &(*pcpu)->next_cpu;
cpu_index++; cpu_index++;
} }
cpu->cpu_index = cpu_index; cpu->cpu_index = cpu_index;
@ -398,7 +392,7 @@ void cpu_exec_init(CPUArchState *env)
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
cpu->thread_id = qemu_get_thread_id(); cpu->thread_id = qemu_get_thread_id();
#endif #endif
*pcpu = cpu; QTAILQ_INSERT_TAIL(&cpus, cpu, node);
#if defined(CONFIG_USER_ONLY) #if defined(CONFIG_USER_ONLY)
cpu_list_unlock(); cpu_list_unlock();
#endif #endif
@ -1762,7 +1756,7 @@ static void tcg_commit(MemoryListener *listener)
/* since each CPU stores ram addresses in its TLB cache, we must /* since each CPU stores ram addresses in its TLB cache, we must
reset the modified entries */ reset the modified entries */
/* XXX: slow ! */ /* XXX: slow ! */
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
tlb_flush(env, 1); tlb_flush(env, 1);

View File

@ -648,7 +648,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
switch (type) { switch (type) {
case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW: case GDB_BREAKPOINT_HW:
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
env = cpu->env_ptr; env = cpu->env_ptr;
err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL); err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
if (err) if (err)
@ -659,7 +659,7 @@ static int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_WRITE: case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS: case GDB_WATCHPOINT_ACCESS:
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
env = cpu->env_ptr; env = cpu->env_ptr;
err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type], err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
NULL); NULL);
@ -686,7 +686,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
switch (type) { switch (type) {
case GDB_BREAKPOINT_SW: case GDB_BREAKPOINT_SW:
case GDB_BREAKPOINT_HW: case GDB_BREAKPOINT_HW:
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
env = cpu->env_ptr; env = cpu->env_ptr;
err = cpu_breakpoint_remove(env, addr, BP_GDB); err = cpu_breakpoint_remove(env, addr, BP_GDB);
if (err) if (err)
@ -697,7 +697,7 @@ static int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
case GDB_WATCHPOINT_WRITE: case GDB_WATCHPOINT_WRITE:
case GDB_WATCHPOINT_READ: case GDB_WATCHPOINT_READ:
case GDB_WATCHPOINT_ACCESS: case GDB_WATCHPOINT_ACCESS:
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
env = cpu->env_ptr; env = cpu->env_ptr;
err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]); err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
if (err) if (err)
@ -720,7 +720,7 @@ static void gdb_breakpoint_remove_all(void)
return; return;
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
env = cpu->env_ptr; env = cpu->env_ptr;
cpu_breakpoint_remove_all(env, BP_GDB); cpu_breakpoint_remove_all(env, BP_GDB);
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
@ -744,7 +744,7 @@ static CPUState *find_cpu(uint32_t thread_id)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (cpu_index(cpu) == thread_id) { if (cpu_index(cpu) == thread_id) {
return cpu; return cpu;
} }
@ -1070,7 +1070,7 @@ static int gdb_handle_packet(GDBState *s, const char *line_buf)
if (s->query_cpu) { if (s->query_cpu) {
snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu)); snprintf(buf, sizeof(buf), "m%x", cpu_index(s->query_cpu));
put_packet(s, buf); put_packet(s, buf);
s->query_cpu = s->query_cpu->next_cpu; s->query_cpu = CPU_NEXT(s->query_cpu);
} else } else
put_packet(s, "l"); put_packet(s, "l");
break; break;

View File

@ -468,7 +468,7 @@ void arm_load_kernel(ARMCPU *cpu, struct arm_boot_info *info)
} }
info->is_linux = is_linux; info->is_linux = is_linux;
for (; cs; cs = cs->next_cpu) { for (; cs; cs = CPU_NEXT(cs)) {
cpu = ARM_CPU(cs); cpu = ARM_CPU(cs);
cpu->env.boot_info = info; cpu->env.boot_info = info;
qemu_register_reset(do_cpu_reset, cpu); qemu_register_reset(do_cpu_reset, cpu);

View File

@ -59,7 +59,7 @@ static void kvmclock_vm_state_change(void *opaque, int running,
if (!cap_clock_ctrl) { if (!cap_clock_ctrl) {
return; return;
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0); ret = kvm_vcpu_ioctl(cpu, KVM_KVMCLOCK_CTRL, 0);
if (ret) { if (ret) {
if (ret != -EINVAL) { if (ret != -EINVAL) {

View File

@ -498,7 +498,7 @@ static void vapic_enable_tpr_reporting(bool enable)
X86CPU *cpu; X86CPU *cpu;
CPUX86State *env; CPUX86State *env;
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
cpu = X86_CPU(cs); cpu = X86_CPU(cs);
env = &cpu->env; env = &cpu->env;
info.apic = env->apic_state; info.apic = env->apic_state;

View File

@ -191,13 +191,12 @@ static void pic_irq_request(void *opaque, int irq, int level)
DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq); DPRINTF("pic_irqs: %s irq %d\n", level? "raise" : "lower", irq);
if (env->apic_state) { if (env->apic_state) {
while (cs) { CPU_FOREACH(cs) {
cpu = X86_CPU(cs); cpu = X86_CPU(cs);
env = &cpu->env; env = &cpu->env;
if (apic_accept_pic_intr(env->apic_state)) { if (apic_accept_pic_intr(env->apic_state)) {
apic_deliver_pic_intr(env->apic_state, level); apic_deliver_pic_intr(env->apic_state, level);
} }
cs = cs->next_cpu;
} }
} else { } else {
if (level) { if (level) {

View File

@ -540,7 +540,7 @@ static DeviceState *ppce500_init_mpic_kvm(PPCE500Params *params,
return NULL; return NULL;
} }
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
if (kvm_openpic_connect_vcpu(dev, cs)) { if (kvm_openpic_connect_vcpu(dev, cs)) {
fprintf(stderr, "%s: failed to connect vcpu to irqchip\n", fprintf(stderr, "%s: failed to connect vcpu to irqchip\n",
__func__); __func__);

View File

@ -443,7 +443,7 @@ void ppce500_set_mpic_proxy(bool enabled)
{ {
CPUState *cs; CPUState *cs;
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs); PowerPCCPU *cpu = POWERPC_CPU(cs);
cpu->env.mpic_proxy = enabled; cpu->env.mpic_proxy = enabled;

View File

@ -187,7 +187,7 @@ static int spapr_fixup_cpu_dt(void *fdt, sPAPREnvironment *spapr)
assert(spapr->cpu_model); assert(spapr->cpu_model);
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
uint32_t associativity[] = {cpu_to_be32(0x5), uint32_t associativity[] = {cpu_to_be32(0x5),
cpu_to_be32(0x0), cpu_to_be32(0x0),
cpu_to_be32(0x0), cpu_to_be32(0x0),
@ -351,7 +351,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
/* This is needed during FDT finalization */ /* This is needed during FDT finalization */
spapr->cpu_model = g_strdup(modelname); spapr->cpu_model = g_strdup(modelname);
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs); PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *env = &cpu->env; CPUPPCState *env = &cpu->env;
PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs); PowerPCCPUClass *pcc = POWERPC_CPU_GET_CLASS(cs);

View File

@ -679,7 +679,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
switch (mflags) { switch (mflags) {
case H_SET_MODE_ENDIAN_BIG: case H_SET_MODE_ENDIAN_BIG:
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
PowerPCCPU *cp = POWERPC_CPU(cs); PowerPCCPU *cp = POWERPC_CPU(cs);
CPUPPCState *env = &cp->env; CPUPPCState *env = &cp->env;
env->spr[SPR_LPCR] &= ~LPCR_ILE; env->spr[SPR_LPCR] &= ~LPCR_ILE;
@ -688,7 +688,7 @@ static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
break; break;
case H_SET_MODE_ENDIAN_LITTLE: case H_SET_MODE_ENDIAN_LITTLE:
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
PowerPCCPU *cp = POWERPC_CPU(cs); PowerPCCPU *cp = POWERPC_CPU(cs);
CPUPPCState *env = &cp->env; CPUPPCState *env = &cp->env;
env->spr[SPR_LPCR] |= LPCR_ILE; env->spr[SPR_LPCR] |= LPCR_ILE;

View File

@ -23,6 +23,7 @@
#include <signal.h> #include <signal.h>
#include "hw/qdev-core.h" #include "hw/qdev-core.h"
#include "exec/hwaddr.h" #include "exec/hwaddr.h"
#include "qemu/queue.h"
#include "qemu/thread.h" #include "qemu/thread.h"
#include "qemu/tls.h" #include "qemu/tls.h"
#include "qemu/typedefs.h" #include "qemu/typedefs.h"
@ -190,7 +191,7 @@ struct CPUState {
struct GDBRegisterState *gdb_regs; struct GDBRegisterState *gdb_regs;
int gdb_num_regs; int gdb_num_regs;
int gdb_num_g_regs; int gdb_num_g_regs;
CPUState *next_cpu; QTAILQ_ENTRY(CPUState) node;
int kvm_fd; int kvm_fd;
bool kvm_vcpu_dirty; bool kvm_vcpu_dirty;
@ -202,7 +203,13 @@ struct CPUState {
uint32_t halted; /* used by alpha, cris, ppc TCG */ uint32_t halted; /* used by alpha, cris, ppc TCG */
}; };
extern CPUState *first_cpu; QTAILQ_HEAD(CPUTailQ, CPUState);
extern struct CPUTailQ cpus;
#define CPU_NEXT(cpu) QTAILQ_NEXT(cpu, node)
#define CPU_FOREACH(cpu) QTAILQ_FOREACH(cpu, &cpus, node)
#define CPU_FOREACH_SAFE(cpu, next_cpu) \
QTAILQ_FOREACH_SAFE(cpu, &cpus, node, next_cpu)
#define first_cpu QTAILQ_FIRST(&cpus)
DECLARE_TLS(CPUState *, current_cpu); DECLARE_TLS(CPUState *, current_cpu);
#define current_cpu tls_var(current_cpu) #define current_cpu tls_var(current_cpu)

View File

@ -1925,7 +1925,7 @@ int kvm_insert_breakpoint(CPUState *cpu, target_ulong addr,
} }
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
err = kvm_update_guest_debug(cpu, 0); err = kvm_update_guest_debug(cpu, 0);
if (err) { if (err) {
return err; return err;
@ -1965,7 +1965,7 @@ int kvm_remove_breakpoint(CPUState *cpu, target_ulong addr,
} }
} }
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
err = kvm_update_guest_debug(cpu, 0); err = kvm_update_guest_debug(cpu, 0);
if (err) { if (err) {
return err; return err;
@ -1982,7 +1982,7 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) { QTAILQ_FOREACH_SAFE(bp, &s->kvm_sw_breakpoints, entry, next) {
if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) { if (kvm_arch_remove_sw_breakpoint(cpu, bp) != 0) {
/* Try harder to find a CPU that currently sees the breakpoint. */ /* Try harder to find a CPU that currently sees the breakpoint. */
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) { if (kvm_arch_remove_sw_breakpoint(cpu, bp) == 0) {
break; break;
} }
@ -1993,7 +1993,7 @@ void kvm_remove_all_breakpoints(CPUState *cpu)
} }
kvm_arch_remove_all_hw_breakpoints(); kvm_arch_remove_all_hw_breakpoints();
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
kvm_update_guest_debug(cpu, 0); kvm_update_guest_debug(cpu, 0);
} }
} }

View File

@ -2668,7 +2668,7 @@ static int fill_note_info(struct elf_note_info *info,
/* read and fill status of all threads */ /* read and fill status of all threads */
cpu_list_lock(); cpu_list_lock();
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (cpu == thread_cpu) { if (cpu == thread_cpu) {
continue; continue;
} }

View File

@ -117,10 +117,14 @@ void fork_end(int child)
{ {
mmap_fork_end(child); mmap_fork_end(child);
if (child) { if (child) {
CPUState *cpu, *next_cpu;
/* Child processes created by fork() only have a single thread. /* Child processes created by fork() only have a single thread.
Discard information about the parent threads. */ Discard information about the parent threads. */
first_cpu = thread_cpu; CPU_FOREACH_SAFE(cpu, next_cpu) {
first_cpu->next_cpu = NULL; if (cpu != thread_cpu) {
QTAILQ_REMOVE(&cpus, thread_cpu, node);
}
}
pending_cpus = 0; pending_cpus = 0;
pthread_mutex_init(&exclusive_lock, NULL); pthread_mutex_init(&exclusive_lock, NULL);
pthread_mutex_init(&cpu_list_mutex, NULL); pthread_mutex_init(&cpu_list_mutex, NULL);
@ -154,7 +158,7 @@ static inline void start_exclusive(void)
pending_cpus = 1; pending_cpus = 1;
/* Make all other cpus stop executing. */ /* Make all other cpus stop executing. */
for (other_cpu = first_cpu; other_cpu; other_cpu = other_cpu->next_cpu) { CPU_FOREACH(other_cpu) {
if (other_cpu->running) { if (other_cpu->running) {
pending_cpus++; pending_cpus++;
cpu_exit(other_cpu); cpu_exit(other_cpu);

View File

@ -5113,25 +5113,12 @@ abi_long do_syscall(void *cpu_env, int num, abi_long arg1,
Do thread termination if we have more then one thread. */ Do thread termination if we have more then one thread. */
/* FIXME: This probably breaks if a signal arrives. We should probably /* FIXME: This probably breaks if a signal arrives. We should probably
be disabling signals. */ be disabling signals. */
if (first_cpu->next_cpu) { if (CPU_NEXT(first_cpu)) {
TaskState *ts; TaskState *ts;
CPUState **lastp;
CPUState *p;
cpu_list_lock(); cpu_list_lock();
lastp = &first_cpu;
p = first_cpu;
while (p && p != cpu) {
lastp = &p->next_cpu;
p = p->next_cpu;
}
/* If we didn't find the CPU for this thread then something is
horribly wrong. */
if (!p) {
abort();
}
/* Remove the CPU from the list. */ /* Remove the CPU from the list. */
*lastp = p->next_cpu; QTAILQ_REMOVE(&cpus, cpu, node);
cpu_list_unlock(); cpu_list_unlock();
ts = ((CPUArchState *)cpu_env)->opaque; ts = ((CPUArchState *)cpu_env)->opaque;
if (ts->child_tidptr) { if (ts->child_tidptr) {

View File

@ -270,7 +270,7 @@ static CPUState *find_paging_enabled_cpu(CPUState *start_cpu)
{ {
CPUState *cpu; CPUState *cpu;
for (cpu = start_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (cpu_paging_enabled(cpu)) { if (cpu_paging_enabled(cpu)) {
return cpu; return cpu;
} }
@ -289,7 +289,8 @@ void qemu_get_guest_memory_mapping(MemoryMappingList *list,
first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu); first_paging_enabled_cpu = find_paging_enabled_cpu(first_cpu);
if (first_paging_enabled_cpu) { if (first_paging_enabled_cpu) {
for (cpu = first_paging_enabled_cpu; cpu != NULL; cpu = cpu->next_cpu) { for (cpu = first_paging_enabled_cpu; cpu != NULL;
cpu = CPU_NEXT(cpu)) {
Error *err = NULL; Error *err = NULL;
cpu_get_memory_mapping(cpu, list, &err); cpu_get_memory_mapping(cpu, list, &err);
if (err) { if (err) {

View File

@ -2002,7 +2002,7 @@ static void do_info_numa(Monitor *mon, const QDict *qdict)
monitor_printf(mon, "%d nodes\n", nb_numa_nodes); monitor_printf(mon, "%d nodes\n", nb_numa_nodes);
for (i = 0; i < nb_numa_nodes; i++) { for (i = 0; i < nb_numa_nodes; i++) {
monitor_printf(mon, "node %d cpus:", i); monitor_printf(mon, "node %d cpus:", i);
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
if (cpu->numa_node == i) { if (cpu->numa_node == i) {
monitor_printf(mon, " %d", cpu->cpu_index); monitor_printf(mon, " %d", cpu->cpu_index);
} }

View File

@ -1231,8 +1231,7 @@ void cpu_x86_inject_mce(Monitor *mon, X86CPU *cpu, int bank,
params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV; params.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
params.addr = 0; params.addr = 0;
params.misc = 0; params.misc = 0;
for (other_cs = first_cpu; other_cs != NULL; CPU_FOREACH(other_cs) {
other_cs = other_cs->next_cpu) {
if (other_cs == cs) { if (other_cs == cs) {
continue; continue;
} }

View File

@ -610,7 +610,7 @@ void helper_mwait(CPUX86State *env, int next_eip_addend)
cpu = x86_env_get_cpu(env); cpu = x86_env_get_cpu(env);
cs = CPU(cpu); cs = CPU(cpu);
/* XXX: not complete but not completely erroneous */ /* XXX: not complete but not completely erroneous */
if (cs->cpu_index != 0 || cs->next_cpu != NULL) { if (cs->cpu_index != 0 || CPU_NEXT(cs) != NULL) {
/* more than one CPU: do not sleep because another CPU may /* more than one CPU: do not sleep because another CPU may
wake this one */ wake this one */
} else { } else {

View File

@ -1699,15 +1699,14 @@ target_ulong helper_dvpe(CPUMIPSState *env)
CPUState *other_cs = first_cpu; CPUState *other_cs = first_cpu;
target_ulong prev = env->mvp->CP0_MVPControl; target_ulong prev = env->mvp->CP0_MVPControl;
do { CPU_FOREACH(other_cs) {
MIPSCPU *other_cpu = MIPS_CPU(other_cs); MIPSCPU *other_cpu = MIPS_CPU(other_cs);
/* Turn off all VPEs except the one executing the dvpe. */ /* Turn off all VPEs except the one executing the dvpe. */
if (&other_cpu->env != env) { if (&other_cpu->env != env) {
other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP); other_cpu->env.mvp->CP0_MVPControl &= ~(1 << CP0MVPCo_EVP);
mips_vpe_sleep(other_cpu); mips_vpe_sleep(other_cpu);
} }
other_cs = other_cs->next_cpu; }
} while (other_cs);
return prev; return prev;
} }
@ -1716,7 +1715,7 @@ target_ulong helper_evpe(CPUMIPSState *env)
CPUState *other_cs = first_cpu; CPUState *other_cs = first_cpu;
target_ulong prev = env->mvp->CP0_MVPControl; target_ulong prev = env->mvp->CP0_MVPControl;
do { CPU_FOREACH(other_cs) {
MIPSCPU *other_cpu = MIPS_CPU(other_cs); MIPSCPU *other_cpu = MIPS_CPU(other_cs);
if (&other_cpu->env != env if (&other_cpu->env != env
@ -1726,8 +1725,7 @@ target_ulong helper_evpe(CPUMIPSState *env)
other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP); other_cpu->env.mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
mips_vpe_wake(other_cpu); /* And wake it up. */ mips_vpe_wake(other_cpu); /* And wake it up. */
} }
other_cs = other_cs->next_cpu; }
} while (other_cs);
return prev; return prev;
} }
#endif /* !CONFIG_USER_ONLY */ #endif /* !CONFIG_USER_ONLY */

View File

@ -1002,7 +1002,7 @@ void helper_msgsnd(target_ulong rb)
return; return;
} }
for (cs = first_cpu; cs != NULL; cs = cs->next_cpu) { CPU_FOREACH(cs) {
PowerPCCPU *cpu = POWERPC_CPU(cs); PowerPCCPU *cpu = POWERPC_CPU(cs);
CPUPPCState *cenv = &cpu->env; CPUPPCState *cenv = &cpu->env;

View File

@ -183,12 +183,12 @@ uint32_t HELPER(servc)(CPUS390XState *env, uint64_t r1, uint64_t r2)
#ifndef CONFIG_USER_ONLY #ifndef CONFIG_USER_ONLY
static void cpu_reset_all(void) static void cpu_reset_all(void)
{ {
CPUState *cpu; CPUState *cs;
S390CPUClass *scc; S390CPUClass *scc;
for (cpu = first_cpu; cpu; cpu = cpu->next_cpu) { CPU_FOREACH(cs) {
scc = S390_CPU_GET_CLASS(CPU(cpu)); scc = S390_CPU_GET_CLASS(cs);
scc->cpu_reset(CPU(cpu)); scc->cpu_reset(cs);
} }
} }

View File

@ -696,7 +696,7 @@ void tb_flush(CPUArchState *env1)
} }
tcg_ctx.tb_ctx.nb_tbs = 0; tcg_ctx.tb_ctx.nb_tbs = 0;
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *)); memset(env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof(void *));
@ -850,7 +850,7 @@ void tb_phys_invalidate(TranslationBlock *tb, tb_page_addr_t page_addr)
/* remove the TB from the hash list */ /* remove the TB from the hash list */
h = tb_jmp_cache_hash_func(tb->pc); h = tb_jmp_cache_hash_func(tb->pc);
for (cpu = first_cpu; cpu != NULL; cpu = cpu->next_cpu) { CPU_FOREACH(cpu) {
CPUArchState *env = cpu->env_ptr; CPUArchState *env = cpu->env_ptr;
if (env->tb_jmp_cache[h] == tb) { if (env->tb_jmp_cache[h] == tb) {