@@ -39,7 +39,10 @@ struct AccelOpsClass {
bool (*cpu_target_realize)(CPUState *cpu, Error **errp);
void (*cpu_reset_hold)(CPUState *cpu);
- void (*create_vcpu_thread)(CPUState *cpu); /* MANDATORY NON-NULL */
+ /* Either cpu_thread_routine() or create_vcpu_thread() is mandatory */
+ void *(*cpu_thread_routine)(void *);
+ void (*thread_precreate)(CPUState *cpu);
+ void (*create_vcpu_thread)(CPUState *cpu);
void (*kick_vcpu_thread)(CPUState *cpu);
bool (*cpu_thread_is_idle)(CPUState *cpu);
@@ -11,6 +11,7 @@
#include "qemu/accel.h"
#include "qemu/target-info.h"
#include "system/accel-ops.h"
+#include "system/cpus.h"
#include "accel/accel-cpu.h"
#include "accel-internal.h"
@@ -104,7 +105,20 @@ void accel_create_vcpu_thread(AccelState *accel, CPUState *cpu)
if (ac->ops->create_vcpu_thread != NULL) {
ac->ops->create_vcpu_thread(cpu);
} else {
- g_assert_not_reached();
+ char thread_name[VCPU_THREAD_NAME_SIZE];
+
+ assert(ac->name);
+ assert(ac->ops->cpu_thread_routine);
+
+ if (ac->ops->thread_precreate) {
+ ac->ops->thread_precreate(cpu);
+ }
+
+ snprintf(thread_name, VCPU_THREAD_NAME_SIZE, "CPU %d/%s",
+ cpu->cpu_index, ac->name);
+ qemu_thread_create(cpu->thread, thread_name,
+ ac->ops->cpu_thread_routine,
+ cpu, QEMU_THREAD_JOINABLE);
}
}
@@ -671,7 +671,7 @@ void cpu_remove_sync(CPUState *cpu)
void cpus_register_accel(const AccelOpsClass *ops)
{
assert(ops != NULL);
- assert(ops->create_vcpu_thread != NULL); /* mandatory */
+ assert(ops->create_vcpu_thread || ops->cpu_thread_routine);
cpus_accel = ops;
}
In order to have a generic function creating threads, introduce the thread_precreate() and cpu_thread_routine() handlers. Signed-off-by: Philippe Mathieu-Daudé <philmd@linaro.org> --- include/system/accel-ops.h | 5 ++++- accel/accel-common.c | 16 +++++++++++++++- system/cpus.c | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-)