Multiple multi-arch targets may wish to implement cpu_list(). When the command is called each should be called one after other. Create a list to allow registrations. When cpu_list() is called the list is iterated calling all implementors.
The original singleton #define'able cpu_list() mechanism remains in place to allow gradual conversion of the target arches to the new way. cpu_list_add() needs to visible from target-foo/*.c which means it cannot be placed in cpus.c (common-obj). So put it in cpu-exec-common.c. For consistency, move cpu_list() alongside it. Signed-off-by: Peter Crosthwaite <crosthwaite.pe...@gmail.com> --- cpu-exec-common.c | 32 ++++++++++++++++++++++++++++++++ cpus.c | 8 -------- include/sysemu/cpus.h | 7 +++++++ 3 files changed, 39 insertions(+), 8 deletions(-) diff --git a/cpu-exec-common.c b/cpu-exec-common.c index 3d87c59..10a6634 100644 --- a/cpu-exec-common.c +++ b/cpu-exec-common.c @@ -74,3 +74,35 @@ typedef struct CPUListFn { void (*do_cpu_list)(FILE *f, fprintf_function cpu_fprintf); QLIST_ENTRY(CPUListFn) list; } CPUListFn; + +static bool cpu_list_list_inited; +static QLIST_HEAD(, CPUListFn) cpu_list_list; + +void cpu_list_add(void (*fn)(FILE *, fprintf_function)) +{ + CPUListFn *lelem = g_malloc0(sizeof(*lelem)); + + if (!cpu_list_list_inited) { + cpu_list_list_inited = true; + QLIST_INIT(&cpu_list_list); + } + + lelem->do_cpu_list = fn; + QLIST_INSERT_HEAD(&cpu_list_list, lelem, list); +} + +void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) +{ + CPUListFn *c; + + /* XXX: implement xxx_cpu_list for targets that still miss it */ +#if defined(cpu_list) + cpu_list(f, cpu_fprintf); +#endif + if (!cpu_list_list_inited) { + return; + } + QLIST_FOREACH(c, &cpu_list_list, list) { + c->do_cpu_list(f, cpu_fprintf); + } +} diff --git a/cpus.c b/cpus.c index b00a423..f6b448b 100644 --- a/cpus.c +++ b/cpus.c @@ -1437,14 +1437,6 @@ static void tcg_exec_all(void) exit_request = 0; } -void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg) -{ - /* XXX: implement xxx_cpu_list for targets that still miss it */ -#if defined(cpu_list) - cpu_list(f, cpu_fprintf); -#endif -} - CpuInfoList *qmp_query_cpus(Error **errp) { CpuInfoList *head = NULL, *cur_item = NULL; diff --git a/include/sysemu/cpus.h b/include/sysemu/cpus.h index 3f162a9..e8f8763 100644 --- a/include/sysemu/cpus.h +++ b/include/sysemu/cpus.h @@ -24,6 +24,13 @@ extern int smp_threads; #define smp_threads 1 #endif +void cpu_list_add(void (*fn)(FILE *, fprintf_function cpu_fprintf)); void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg); +#define cpu_list_register(fn) \ +static __attribute__((constructor)) void register_cpu_list ## fn(void) \ +{ \ + cpu_list_add(fn); \ +} + #endif -- 1.9.1