mirror of https://github.com/xemu-project/xemu.git
util/main-loop: Introduce the main loop into QOM
'event-loop-base' provides basic property handling for all 'AioContext' based event loops. So let's define a new 'MainLoopClass' that inherits from it. This will permit tweaking the main loop's properties through qapi as well as through the command line using the '-object' keyword[1]. Only one instance of 'MainLoopClass' might be created at any time. 'EventLoopBaseClass' learns a new callback, 'can_be_deleted()' so as to mark 'MainLoop' as non-deletable. [1] For example: -object main-loop,id=main-loop,aio-max-batch=<value> Signed-off-by: Nicolas Saenz Julienne <nsaenzju@redhat.com> Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com> Acked-by: Markus Armbruster <armbru@redhat.com> Message-id: 20220425075723.20019-3-nsaenzju@redhat.com Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
7d5983e3c8
commit
70ac26b9e5
|
@ -73,10 +73,23 @@ static void event_loop_base_complete(UserCreatable *uc, Error **errp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool event_loop_base_can_be_deleted(UserCreatable *uc)
|
||||||
|
{
|
||||||
|
EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
|
||||||
|
EventLoopBase *backend = EVENT_LOOP_BASE(uc);
|
||||||
|
|
||||||
|
if (bc->can_be_deleted) {
|
||||||
|
return bc->can_be_deleted(backend);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
|
static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
|
||||||
{
|
{
|
||||||
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
|
UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
|
||||||
ucc->complete = event_loop_base_complete;
|
ucc->complete = event_loop_base_complete;
|
||||||
|
ucc->can_be_deleted = event_loop_base_can_be_deleted;
|
||||||
|
|
||||||
object_class_property_add(klass, "aio-max-batch", "int",
|
object_class_property_add(klass, "aio-max-batch", "int",
|
||||||
event_loop_base_get_param,
|
event_loop_base_get_param,
|
||||||
|
|
|
@ -26,9 +26,19 @@
|
||||||
#define QEMU_MAIN_LOOP_H
|
#define QEMU_MAIN_LOOP_H
|
||||||
|
|
||||||
#include "block/aio.h"
|
#include "block/aio.h"
|
||||||
|
#include "qom/object.h"
|
||||||
|
#include "sysemu/event-loop-base.h"
|
||||||
|
|
||||||
#define SIG_IPI SIGUSR1
|
#define SIG_IPI SIGUSR1
|
||||||
|
|
||||||
|
#define TYPE_MAIN_LOOP "main-loop"
|
||||||
|
OBJECT_DECLARE_TYPE(MainLoop, MainLoopClass, MAIN_LOOP)
|
||||||
|
|
||||||
|
struct MainLoop {
|
||||||
|
EventLoopBase parent_obj;
|
||||||
|
};
|
||||||
|
typedef struct MainLoop MainLoop;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* qemu_init_main_loop: Set up the process so that it can run the main loop.
|
* qemu_init_main_loop: Set up the process so that it can run the main loop.
|
||||||
*
|
*
|
||||||
|
|
|
@ -25,6 +25,7 @@ struct EventLoopBaseClass {
|
||||||
|
|
||||||
void (*init)(EventLoopBase *base, Error **errp);
|
void (*init)(EventLoopBase *base, Error **errp);
|
||||||
void (*update_params)(EventLoopBase *base, Error **errp);
|
void (*update_params)(EventLoopBase *base, Error **errp);
|
||||||
|
bool (*can_be_deleted)(EventLoopBase *base);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EventLoopBase {
|
struct EventLoopBase {
|
||||||
|
|
|
@ -3053,7 +3053,8 @@ libqemuutil = static_library('qemuutil',
|
||||||
sources: util_ss.sources() + stub_ss.sources() + genh,
|
sources: util_ss.sources() + stub_ss.sources() + genh,
|
||||||
dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
|
dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
|
||||||
qemuutil = declare_dependency(link_with: libqemuutil,
|
qemuutil = declare_dependency(link_with: libqemuutil,
|
||||||
sources: genh + version_res)
|
sources: genh + version_res,
|
||||||
|
dependencies: [event_loop_base])
|
||||||
|
|
||||||
if have_system or have_user
|
if have_system or have_user
|
||||||
decodetree = generator(find_program('scripts/decodetree.py'),
|
decodetree = generator(find_program('scripts/decodetree.py'),
|
||||||
|
|
|
@ -540,6 +540,17 @@
|
||||||
'*poll-grow': 'int',
|
'*poll-grow': 'int',
|
||||||
'*poll-shrink': 'int' } }
|
'*poll-shrink': 'int' } }
|
||||||
|
|
||||||
|
##
|
||||||
|
# @MainLoopProperties:
|
||||||
|
#
|
||||||
|
# Properties for the main-loop object.
|
||||||
|
#
|
||||||
|
# Since: 7.1
|
||||||
|
##
|
||||||
|
{ 'struct': 'MainLoopProperties',
|
||||||
|
'base': 'EventLoopBaseProperties',
|
||||||
|
'data': {} }
|
||||||
|
|
||||||
##
|
##
|
||||||
# @MemoryBackendProperties:
|
# @MemoryBackendProperties:
|
||||||
#
|
#
|
||||||
|
@ -830,6 +841,7 @@
|
||||||
{ 'name': 'input-linux',
|
{ 'name': 'input-linux',
|
||||||
'if': 'CONFIG_LINUX' },
|
'if': 'CONFIG_LINUX' },
|
||||||
'iothread',
|
'iothread',
|
||||||
|
'main-loop',
|
||||||
{ 'name': 'memory-backend-epc',
|
{ 'name': 'memory-backend-epc',
|
||||||
'if': 'CONFIG_LINUX' },
|
'if': 'CONFIG_LINUX' },
|
||||||
'memory-backend-file',
|
'memory-backend-file',
|
||||||
|
@ -895,6 +907,7 @@
|
||||||
'input-linux': { 'type': 'InputLinuxProperties',
|
'input-linux': { 'type': 'InputLinuxProperties',
|
||||||
'if': 'CONFIG_LINUX' },
|
'if': 'CONFIG_LINUX' },
|
||||||
'iothread': 'IothreadProperties',
|
'iothread': 'IothreadProperties',
|
||||||
|
'main-loop': 'MainLoopProperties',
|
||||||
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
|
'memory-backend-epc': { 'type': 'MemoryBackendEpcProperties',
|
||||||
'if': 'CONFIG_LINUX' },
|
'if': 'CONFIG_LINUX' },
|
||||||
'memory-backend-file': 'MemoryBackendFileProperties',
|
'memory-backend-file': 'MemoryBackendFileProperties',
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "qemu/error-report.h"
|
#include "qemu/error-report.h"
|
||||||
#include "qemu/queue.h"
|
#include "qemu/queue.h"
|
||||||
#include "qemu/compiler.h"
|
#include "qemu/compiler.h"
|
||||||
|
#include "qom/object.h"
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
@ -184,6 +185,61 @@ int qemu_init_main_loop(Error **errp)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void main_loop_update_params(EventLoopBase *base, Error **errp)
|
||||||
|
{
|
||||||
|
if (!qemu_aio_context) {
|
||||||
|
error_setg(errp, "qemu aio context not ready");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aio_context_set_aio_params(qemu_aio_context, base->aio_max_batch, errp);
|
||||||
|
}
|
||||||
|
|
||||||
|
MainLoop *mloop;
|
||||||
|
|
||||||
|
static void main_loop_init(EventLoopBase *base, Error **errp)
|
||||||
|
{
|
||||||
|
MainLoop *m = MAIN_LOOP(base);
|
||||||
|
|
||||||
|
if (mloop) {
|
||||||
|
error_setg(errp, "only one main-loop instance allowed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
main_loop_update_params(base, errp);
|
||||||
|
|
||||||
|
mloop = m;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool main_loop_can_be_deleted(EventLoopBase *base)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void main_loop_class_init(ObjectClass *oc, void *class_data)
|
||||||
|
{
|
||||||
|
EventLoopBaseClass *bc = EVENT_LOOP_BASE_CLASS(oc);
|
||||||
|
|
||||||
|
bc->init = main_loop_init;
|
||||||
|
bc->update_params = main_loop_update_params;
|
||||||
|
bc->can_be_deleted = main_loop_can_be_deleted;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const TypeInfo main_loop_info = {
|
||||||
|
.name = TYPE_MAIN_LOOP,
|
||||||
|
.parent = TYPE_EVENT_LOOP_BASE,
|
||||||
|
.class_init = main_loop_class_init,
|
||||||
|
.instance_size = sizeof(MainLoop),
|
||||||
|
};
|
||||||
|
|
||||||
|
static void main_loop_register_types(void)
|
||||||
|
{
|
||||||
|
type_register_static(&main_loop_info);
|
||||||
|
}
|
||||||
|
|
||||||
|
type_init(main_loop_register_types)
|
||||||
|
|
||||||
static int max_priority;
|
static int max_priority;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
|
|
Loading…
Reference in New Issue