On Wed, Sep 06, 2017 at 21:07:06 +0300, Lluís Vilanova wrote: > Keep a translation between instrumentation's QICPU and CPUState objects to > avoid > exposing QEMU's internals to instrumentation clients. > > Signed-off-by: Lluís Vilanova <vilan...@ac.upc.edu> (snip) > diff --git a/instrument/control.c b/instrument/control.c > index 2c2781beeb..83453ea561 100644 > --- a/instrument/control.c > +++ b/instrument/control.c > @@ -13,10 +13,32 @@ > #include "instrument/load.h" > #include "instrument/qemu-instr/control.h" > #include "instrument/qemu-instr/visibility.h" > +#include "qom/cpu.h" > + > > __thread InstrState instr_cur_state; > > > +unsigned int instr_cpus_count; > +CPUState **instr_cpus; > + > +void instr_cpu_add(CPUState *vcpu) > +{ > + unsigned int idx = vcpu->cpu_index; > + if (idx >= instr_cpus_count) { > + instr_cpus_count = idx + 1; > + instr_cpus = realloc(instr_cpus, sizeof(*instr_cpus) * > instr_cpus_count); > + } > + instr_cpus[idx] = vcpu; > +} > + > +void instr_cpu_remove(CPUState *vcpu) > +{ > + unsigned int idx = vcpu->cpu_index; > + instr_cpus[idx] = NULL; > +}
instr_cpus_count and instr_cpus are both modified with cpu_list_lock. However, other readers do not acquire this same lock. This gets messy when you try to implement something like "vcpu_for_each", which is very useful when you load an instrumentation tool once the program is running (otherwise the tool cannot know for sure what the vCPUs are). This vcpu_for_each would also have to take cpu_list_lock, for otherwise it'd miss new threads being added. As you can imagine this gets messy pretty quickly, given that you have your own lock here. I went with having my own hash table (a list would be fine too), protected with the same "instr_lock" you have (i.e. the recursive mutex). An unrelated comment: your usage of get/set/put confuses me. I'd expect those to work on refcounted items; instead you use them for instance to hide a cast (cpu_set) or to create/destroy (e.g. handle_get/put). E.