diff --git a/src/emu/cpu.c b/src/emu/cpu.c index 16220a7..74b8678 100644 --- a/src/emu/cpu.c +++ b/src/emu/cpu.c @@ -3,6 +3,7 @@ #include "cpu.h" +#include "loom.h" #include "chan.h" #include "value.h" #include "utlist.h" @@ -28,16 +29,24 @@ static int chan_type[] = { }; void -cpu_init_begin(struct cpu *cpu, int phyid, int is_virtual) +cpu_init_begin(struct cpu *cpu, int index, int phyid, int is_virtual) { memset(cpu, 0, sizeof(struct cpu)); + cpu->index = index; cpu->phyid = phyid; cpu->is_virtual = is_virtual; + cpu->gindex = -1; dbg("cpu init %d", phyid); } +int +cpu_get_index(struct cpu *cpu) +{ + return cpu->index; +} + int cpu_get_phyid(struct cpu *cpu) { @@ -56,23 +65,41 @@ cpu_set_loom(struct cpu *cpu, struct loom *loom) cpu->loom = loom; } -void -cpu_set_name(struct cpu *cpu, const char *name) +static int +set_name(struct cpu *cpu) { - if (snprintf(cpu->name, PATH_MAX, "%s", name) >= PATH_MAX) - die("cpu name too long"); + size_t i = loom_get_gindex(cpu->loom); + size_t j = cpu_get_phyid(cpu); + int n; + + if (cpu->is_virtual) + n = snprintf(cpu->name, PATH_MAX, "vCPU %ld.*", i); + else + n = snprintf(cpu->name, PATH_MAX, " CPU %ld.%ld", i, j); + + if (n >= PATH_MAX) { + err("cpu name too long"); + return -1; + } + + return 0; } int cpu_init_end(struct cpu *cpu) { - if (strlen(cpu->name) == 0) { - err("cpu name not set"); + if (cpu->gindex < 0) { + err("cpu gindex not set"); return -1; } - if (cpu->gindex < 0) { - err("cpu gindex not set"); + if (cpu->loom == NULL) { + err("cpu loom not set"); + return -1; + } + + if (set_name(cpu) != 0) { + err("set_name failed"); return -1; } diff --git a/src/emu/cpu.h b/src/emu/cpu.h index 31981e2..d41df11 100644 --- a/src/emu/cpu.h +++ b/src/emu/cpu.h @@ -4,7 +4,8 @@ #ifndef CPU_H #define CPU_H -struct cpu; /* Needed for thread */ +struct cpu; /* Needed for thread and loom */ +struct loom; #include "thread.h" #include "chan.h" @@ -30,8 +31,8 @@ struct cpu { char name[PATH_MAX]; int is_init; - /* Logical index: 0 to ncpus - 1 */ - //int index; + /* Logical index: 0 to ncpus - 1, and -1 for virtual */ + int index; /* Physical id: as reported by lscpu(1) */ int phyid; @@ -64,8 +65,9 @@ struct cpu { UT_hash_handle hh; /* CPUs in the loom */ }; - void cpu_init_begin(struct cpu *cpu, int phyid, int is_virtual); + void cpu_init_begin(struct cpu *cpu, int index, int phyid, int is_virtual); USE_RET int cpu_get_phyid(struct cpu *cpu); +USE_RET int cpu_get_index(struct cpu *cpu); void cpu_set_gindex(struct cpu *cpu, int64_t gindex); void cpu_set_loom(struct cpu *cpu, struct loom *loom); void cpu_set_name(struct cpu *cpu, const char *name); diff --git a/src/emu/loom.c b/src/emu/loom.c index 2a987b2..1d76365 100644 --- a/src/emu/loom.c +++ b/src/emu/loom.c @@ -67,7 +67,7 @@ loom_init_begin(struct loom *loom, const char *name) set_hostname(loom->hostname, loom->name); loom->id = loom->name; - cpu_init_begin(&loom->vcpu, -1, 1); + cpu_init_begin(&loom->vcpu, -1, -1, 1); cpu_set_loom(&loom->vcpu, loom); dbg("creating new loom %s", loom->id); @@ -98,6 +98,20 @@ loom_find_cpu(struct loom *loom, int phyid) return cpu; } +struct cpu * +loom_get_cpu(struct loom *loom, int index) +{ + if (index == -1) + return &loom->vcpu; + + if (index < 0 || (size_t) index >= loom->ncpus) { + err("cpu index out of bounds"); + return NULL; + } + + return loom->cpus_array[index]; +} + int loom_add_cpu(struct loom *loom, struct cpu *cpu) { @@ -183,6 +197,27 @@ loom_init_end(struct loom *loom) } } + /* Populate cpus_array */ + loom->cpus_array = calloc(loom->ncpus, sizeof(struct cpu *)); + if (loom->cpus_array == NULL) { + err("calloc failed:"); + return -1; + } + for (struct cpu *c = loom->cpus; c; c = c->hh.next) { + int index = cpu_get_index(c); + if (index < 0 || (size_t) index >= loom->ncpus) { + err("cpu index out of bounds"); + return -1; + } + + if (loom->cpus_array[index] != NULL) { + err("cpu with index %d already taken", index); + return -1; + } + + loom->cpus_array[index] = c; + } + loom->is_init = 1; return 0; diff --git a/src/emu/loom.h b/src/emu/loom.h index 2cda41b..8baf461 100644 --- a/src/emu/loom.h +++ b/src/emu/loom.h @@ -4,7 +4,7 @@ #ifndef LOOM_H #define LOOM_H -//struct loom; +struct loom; #include #include @@ -33,6 +33,9 @@ struct loom { /* Physical CPUs hash table by phyid */ struct cpu *cpus; + /* Array of CPUs indexed by logic index */ + struct cpu **cpus_array; + /* Virtual CPU */ struct cpu vcpu; @@ -54,6 +57,7 @@ int loom_add_cpu(struct loom *loom, struct cpu *cpu); int64_t loom_get_gindex(struct loom *loom); void loom_set_gindex(struct loom *loom, int64_t gindex); struct cpu *loom_find_cpu(struct loom *loom, int phyid); +struct cpu *loom_get_cpu(struct loom *loom, int index); void loom_set_vcpu(struct loom *loom, struct cpu *vcpu); struct cpu *loom_get_vcpu(struct loom *loom); struct proc *loom_find_proc(struct loom *loom, pid_t pid); diff --git a/src/emu/metadata.c b/src/emu/metadata.c index 945aa79..a376b7c 100644 --- a/src/emu/metadata.c +++ b/src/emu/metadata.c @@ -97,8 +97,7 @@ load_cpus(struct loom *loom, JSON_Object *meta) /* Cast from double */ int index = (int) json_object_get_number(jcpu, "index"); - /* FIXME: Use phyid instead */ - //int phyid = (int) json_object_get_number(jcpu, "phyid"); + int phyid = (int) json_object_get_number(jcpu, "phyid"); struct cpu *cpu = calloc(1, sizeof(struct cpu)); if (cpu == NULL) { @@ -106,7 +105,7 @@ load_cpus(struct loom *loom, JSON_Object *meta) return -1; } - cpu_init_begin(cpu, index, 0); + cpu_init_begin(cpu, index, phyid, 0); if (loom_add_cpu(loom, cpu) != 0) { err("loom_add_cpu() failed"); diff --git a/src/emu/ovni/event.c b/src/emu/ovni/event.c index 6f34916..a3041a5 100644 --- a/src/emu/ovni/event.c +++ b/src/emu/ovni/event.c @@ -23,12 +23,12 @@ pre_thread_execute(struct emu *emu, struct thread *th) return -1; } - int cpuid = emu->ev->payload->i32[0]; - struct cpu *cpu = loom_find_cpu(emu->loom, cpuid); + int index = emu->ev->payload->i32[0]; + struct cpu *cpu = loom_get_cpu(emu->loom, index); if (cpu == NULL) { - err("cannot find CPU with phyid %d in loom %s", - cpuid, emu->loom->id); + err("cannot find CPU with index %d in loom %s", + index, emu->loom->id); return -1; } @@ -213,12 +213,12 @@ pre_affinity_set(struct emu *emu) return -1; } - /* Migrate current cpu to the one at phyid */ - int phyid = emu->ev->payload->i32[0]; - struct cpu *newcpu = loom_find_cpu(emu->loom, phyid); + /* Migrate current cpu to the one at index */ + int index = emu->ev->payload->i32[0]; + struct cpu *newcpu = loom_get_cpu(emu->loom, index); if (newcpu == NULL) { - err("cannot find cpu with phyid %d", phyid); + err("cannot find cpu with index %d", index); return -1; } @@ -244,7 +244,7 @@ pre_affinity_set(struct emu *emu) static int pre_affinity_remote(struct emu *emu) { - int32_t phyid = emu->ev->payload->i32[0]; + int32_t index = emu->ev->payload->i32[0]; int32_t tid = emu->ev->payload->i32[1]; struct thread *remote_th = proc_find_thread(emu->proc, tid); @@ -276,10 +276,10 @@ pre_affinity_remote(struct emu *emu) return -1; } - /* Migrate current cpu to the one at phyid */ - struct cpu *newcpu = loom_find_cpu(emu->loom, phyid); + /* Migrate current cpu to the one at index */ + struct cpu *newcpu = loom_get_cpu(emu->loom, index); if (newcpu == NULL) { - err("cannot find CPU with phyid %d", phyid); + err("cannot find CPU with index %d", index); return -1; } @@ -293,7 +293,7 @@ pre_affinity_remote(struct emu *emu) return -1; } - dbg("remote_th %d remotely switches to cpu %d", tid, phyid); + dbg("remote_th %d remotely switches to cpu %d", tid, index); return 0; } diff --git a/src/emu/system.c b/src/emu/system.c index baf3a23..7c44ca2 100644 --- a/src/emu/system.c +++ b/src/emu/system.c @@ -278,41 +278,36 @@ init_global_indices(struct system *sys) } static int -init_cpu_name(struct loom *loom, struct cpu *cpu, int virtual) +init_end_system(struct system *sys) { - size_t i = loom_get_gindex(loom); - size_t j = cpu_get_phyid(cpu); - int n = 0; - char name[PATH_MAX]; - - if (virtual) - n = snprintf(name, PATH_MAX, "vCPU %ld.*", i); - else - n = snprintf(name, PATH_MAX, "CPU %ld.%ld", i, j); - - if (n >= PATH_MAX) { - err("cpu name too long"); - return -1; - } - - cpu_set_name(cpu, name); - - return 0; -} - -static int -init_cpu_names(struct system *sys) -{ - for (struct loom *loom = sys->looms; loom; loom = loom->next) { - for (struct cpu *cpu = loom->cpus; cpu; cpu = cpu->hh.next) { - if (init_cpu_name(loom, cpu, 0) != 0) + for (struct loom *l = sys->looms; l; l = l->next) { + for (struct proc *p = l->procs; p; p = p->hh.next) { + for (struct thread *t = p->threads; t; t = t->hh.next) { + if (thread_init_end(t) != 0) { + err("thread_init_end failed"); + return -1; + } + } + if (proc_init_end(p) != 0) { + err("proc_init_end failed"); return -1; + } } - struct cpu *vcpu = loom_get_vcpu(loom); - if (init_cpu_name(loom, vcpu, 1) != 0) + for (struct cpu *cpu = l->cpus; cpu; cpu = cpu->hh.next) { + if (cpu_init_end(cpu) != 0) { + err("cpu_init_end failed"); + return -1; + } + } + if (cpu_init_end(&l->vcpu) != 0) { + err("cpu_init_end failed"); return -1; + } + if (loom_init_end(l) != 0) { + err("loom_init_end failed"); + return -1; + } } - return 0; } @@ -433,40 +428,6 @@ init_offsets(struct system *sys, struct trace *trace) return 0; } -static int -init_end_system(struct system *sys) -{ - for (struct loom *l = sys->looms; l; l = l->next) { - for (struct proc *p = l->procs; p; p = p->hh.next) { - for (struct thread *t = p->threads; t; t = t->hh.next) { - if (thread_init_end(t) != 0) { - err("thread_init_end failed"); - return -1; - } - } - if (proc_init_end(p) != 0) { - err("proc_init_end failed"); - return -1; - } - } - for (struct cpu *cpu = l->cpus; cpu; cpu = cpu->hh.next) { - if (cpu_init_end(cpu) != 0) { - err("cpu_init_end failed"); - return -1; - } - } - if (cpu_init_end(&l->vcpu) != 0) { - err("cpu_init_end failed"); - return -1; - } - if (loom_init_end(l) != 0) { - err("loom_init_end failed"); - return -1; - } - } - return 0; -} - int system_init(struct system *sys, struct emu_args *args, struct trace *trace) { @@ -488,9 +449,8 @@ system_init(struct system *sys, struct emu_args *args, struct trace *trace) /* Now that we have loaded all resources, populate the indices */ init_global_indices(sys); - /* Set CPU names like "CPU 1.34" */ - if (init_cpu_names(sys) != 0) { - err("init_cpu_names() failed"); + if (init_end_system(sys) != 0) { + err("init_end_system failed"); return -1; } @@ -506,11 +466,6 @@ system_init(struct system *sys, struct emu_args *args, struct trace *trace) return -1; } - if (init_end_system(sys) != 0) { - err("init_end_system failed"); - return -1; - } - /* Finaly dump the system */ if (0) print_system(sys); diff --git a/test/unit/cpu.c b/test/unit/cpu.c index 23601e8..4a80425 100644 --- a/test/unit/cpu.c +++ b/test/unit/cpu.c @@ -1,15 +1,20 @@ #include "emu/cpu.h" +#include "emu/loom.h" #include "common.h" static void test_oversubscription(void) { + struct loom loom; + loom_init_begin(&loom, "loom.0"); + struct cpu cpu; int phyid = 0; - cpu_init_begin(&cpu, phyid, 0); - cpu_set_name(&cpu, "cpu0"); + int index = 0; + cpu_init_begin(&cpu, index, phyid, 0); cpu_set_gindex(&cpu, 0); + cpu_set_loom(&cpu, &loom); if (cpu_init_end(&cpu) != 0) die("cpu_init_end failed"); diff --git a/test/unit/loom.c b/test/unit/loom.c index 51377ff..49cee03 100644 --- a/test/unit/loom.c +++ b/test/unit/loom.c @@ -53,7 +53,7 @@ test_negative_cpu(struct loom *loom) die("loom_init_begin failed"); struct cpu cpu; - cpu_init_begin(&cpu, -1, 0); + cpu_init_begin(&cpu, -1, -1, 0); if (loom_add_cpu(loom, &cpu) == 0) die("loom_add_cpu didn't fail"); @@ -68,7 +68,7 @@ test_duplicate_cpus(struct loom *loom) die("loom_init_begin failed"); struct cpu cpu; - cpu_init_begin(&cpu, 123, 0); + cpu_init_begin(&cpu, 123, 123, 0); if (loom_add_cpu(loom, &cpu) != 0) die("loom_add_cpu failed");