mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-11-05 20:35:44 +00:00
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:
parent
25ca6a1f5a
commit
3c02270db9
3 changed files with 40 additions and 0 deletions
29
cpus.c
29
cpus.c
|
@ -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);
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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.
|
||||||
|
|
Loading…
Reference in a new issue