Introduce async_run_on_cpu()

Introduce an asynchronous version of run_on_cpu() i.e. the caller
doesn't have to block till the call back routine finishes execution
on the target vcpu.

Signed-off-by: Chegu Vinod <chegu_vinod@hp.com>
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Juan Quintela <quintela@redhat.com>
This commit is contained in:
Chegu Vinod 2013-06-24 03:49:41 -06:00 committed by Juan Quintela
parent 25ca6a1f5a
commit 3c02270db9
3 changed files with 40 additions and 0 deletions

29
cpus.c
View file

@ -648,6 +648,7 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
wi.func = func; wi.func = func;
wi.data = data; wi.data = data;
wi.free = false;
if (cpu->queued_work_first == NULL) { if (cpu->queued_work_first == NULL) {
cpu->queued_work_first = &wi; cpu->queued_work_first = &wi;
} else { } else {
@ -666,6 +667,31 @@ void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
} }
} }
void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data)
{
struct qemu_work_item *wi;
if (qemu_cpu_is_self(cpu)) {
func(data);
return;
}
wi = g_malloc0(sizeof(struct qemu_work_item));
wi->func = func;
wi->data = data;
wi->free = true;
if (cpu->queued_work_first == NULL) {
cpu->queued_work_first = wi;
} else {
cpu->queued_work_last->next = wi;
}
cpu->queued_work_last = wi;
wi->next = NULL;
wi->done = false;
qemu_cpu_kick(cpu);
}
static void flush_queued_work(CPUState *cpu) static void flush_queued_work(CPUState *cpu)
{ {
struct qemu_work_item *wi; struct qemu_work_item *wi;
@ -678,6 +704,9 @@ static void flush_queued_work(CPUState *cpu)
cpu->queued_work_first = wi->next; cpu->queued_work_first = wi->next;
wi->func(wi->data); wi->func(wi->data);
wi->done = true; wi->done = true;
if (wi->free) {
g_free(wi);
}
} }
cpu->queued_work_last = NULL; cpu->queued_work_last = NULL;
qemu_cond_broadcast(&qemu_work_cond); qemu_cond_broadcast(&qemu_work_cond);

View file

@ -293,6 +293,7 @@ struct qemu_work_item {
void (*func)(void *data); void (*func)(void *data);
void *data; void *data;
int done; int done;
bool free;
}; };

View file

@ -378,6 +378,16 @@ bool cpu_is_stopped(CPUState *cpu);
*/ */
void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data); void run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
/**
* async_run_on_cpu:
* @cpu: The vCPU to run on.
* @func: The function to be executed.
* @data: Data to pass to the function.
*
* Schedules the function @func for execution on the vCPU @cpu asynchronously.
*/
void async_run_on_cpu(CPUState *cpu, void (*func)(void *data), void *data);
/** /**
* qemu_for_each_cpu: * qemu_for_each_cpu:
* @func: The function to be executed. * @func: The function to be executed.