xref: /openbmc/qemu/event-loop-base.c (revision 178bacb66d98d9ee7a702b9f2a4dfcd88b72a9ab)
17d5983e3SNicolas Saenz Julienne /*
27d5983e3SNicolas Saenz Julienne  * QEMU event-loop base
37d5983e3SNicolas Saenz Julienne  *
47d5983e3SNicolas Saenz Julienne  * Copyright (C) 2022 Red Hat Inc
57d5983e3SNicolas Saenz Julienne  *
67d5983e3SNicolas Saenz Julienne  * Authors:
77d5983e3SNicolas Saenz Julienne  *  Stefan Hajnoczi <stefanha@redhat.com>
87d5983e3SNicolas Saenz Julienne  *  Nicolas Saenz Julienne <nsaenzju@redhat.com>
97d5983e3SNicolas Saenz Julienne  *
107d5983e3SNicolas Saenz Julienne  * This work is licensed under the terms of the GNU GPL, version 2 or later.
117d5983e3SNicolas Saenz Julienne  * See the COPYING file in the top-level directory.
127d5983e3SNicolas Saenz Julienne  */
137d5983e3SNicolas Saenz Julienne 
147d5983e3SNicolas Saenz Julienne #include "qemu/osdep.h"
157d5983e3SNicolas Saenz Julienne #include "qom/object_interfaces.h"
167d5983e3SNicolas Saenz Julienne #include "qapi/error.h"
17*71ad4713SNicolas Saenz Julienne #include "block/thread-pool.h"
187d5983e3SNicolas Saenz Julienne #include "sysemu/event-loop-base.h"
197d5983e3SNicolas Saenz Julienne 
207d5983e3SNicolas Saenz Julienne typedef struct {
217d5983e3SNicolas Saenz Julienne     const char *name;
227d5983e3SNicolas Saenz Julienne     ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
237d5983e3SNicolas Saenz Julienne } EventLoopBaseParamInfo;
247d5983e3SNicolas Saenz Julienne 
event_loop_base_instance_init(Object * obj)25*71ad4713SNicolas Saenz Julienne static void event_loop_base_instance_init(Object *obj)
26*71ad4713SNicolas Saenz Julienne {
27*71ad4713SNicolas Saenz Julienne     EventLoopBase *base = EVENT_LOOP_BASE(obj);
28*71ad4713SNicolas Saenz Julienne 
29*71ad4713SNicolas Saenz Julienne     base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
30*71ad4713SNicolas Saenz Julienne }
31*71ad4713SNicolas Saenz Julienne 
327d5983e3SNicolas Saenz Julienne static EventLoopBaseParamInfo aio_max_batch_info = {
337d5983e3SNicolas Saenz Julienne     "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
347d5983e3SNicolas Saenz Julienne };
35*71ad4713SNicolas Saenz Julienne static EventLoopBaseParamInfo thread_pool_min_info = {
36*71ad4713SNicolas Saenz Julienne     "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
37*71ad4713SNicolas Saenz Julienne };
38*71ad4713SNicolas Saenz Julienne static EventLoopBaseParamInfo thread_pool_max_info = {
39*71ad4713SNicolas Saenz Julienne     "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
40*71ad4713SNicolas Saenz Julienne };
417d5983e3SNicolas Saenz Julienne 
event_loop_base_get_param(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)427d5983e3SNicolas Saenz Julienne static void event_loop_base_get_param(Object *obj, Visitor *v,
437d5983e3SNicolas Saenz Julienne         const char *name, void *opaque, Error **errp)
447d5983e3SNicolas Saenz Julienne {
457d5983e3SNicolas Saenz Julienne     EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
467d5983e3SNicolas Saenz Julienne     EventLoopBaseParamInfo *info = opaque;
477d5983e3SNicolas Saenz Julienne     int64_t *field = (void *)event_loop_base + info->offset;
487d5983e3SNicolas Saenz Julienne 
497d5983e3SNicolas Saenz Julienne     visit_type_int64(v, name, field, errp);
507d5983e3SNicolas Saenz Julienne }
517d5983e3SNicolas Saenz Julienne 
event_loop_base_set_param(Object * obj,Visitor * v,const char * name,void * opaque,Error ** errp)527d5983e3SNicolas Saenz Julienne static void event_loop_base_set_param(Object *obj, Visitor *v,
537d5983e3SNicolas Saenz Julienne         const char *name, void *opaque, Error **errp)
547d5983e3SNicolas Saenz Julienne {
557d5983e3SNicolas Saenz Julienne     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
567d5983e3SNicolas Saenz Julienne     EventLoopBase *base = EVENT_LOOP_BASE(obj);
577d5983e3SNicolas Saenz Julienne     EventLoopBaseParamInfo *info = opaque;
587d5983e3SNicolas Saenz Julienne     int64_t *field = (void *)base + info->offset;
597d5983e3SNicolas Saenz Julienne     int64_t value;
607d5983e3SNicolas Saenz Julienne 
617d5983e3SNicolas Saenz Julienne     if (!visit_type_int64(v, name, &value, errp)) {
627d5983e3SNicolas Saenz Julienne         return;
637d5983e3SNicolas Saenz Julienne     }
647d5983e3SNicolas Saenz Julienne 
657d5983e3SNicolas Saenz Julienne     if (value < 0) {
667d5983e3SNicolas Saenz Julienne         error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
677d5983e3SNicolas Saenz Julienne                    info->name, INT64_MAX);
687d5983e3SNicolas Saenz Julienne         return;
697d5983e3SNicolas Saenz Julienne     }
707d5983e3SNicolas Saenz Julienne 
717d5983e3SNicolas Saenz Julienne     *field = value;
727d5983e3SNicolas Saenz Julienne 
737d5983e3SNicolas Saenz Julienne     if (bc->update_params) {
747d5983e3SNicolas Saenz Julienne         bc->update_params(base, errp);
757d5983e3SNicolas Saenz Julienne     }
767d5983e3SNicolas Saenz Julienne 
777d5983e3SNicolas Saenz Julienne     return;
787d5983e3SNicolas Saenz Julienne }
797d5983e3SNicolas Saenz Julienne 
event_loop_base_complete(UserCreatable * uc,Error ** errp)807d5983e3SNicolas Saenz Julienne static void event_loop_base_complete(UserCreatable *uc, Error **errp)
817d5983e3SNicolas Saenz Julienne {
827d5983e3SNicolas Saenz Julienne     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
837d5983e3SNicolas Saenz Julienne     EventLoopBase *base = EVENT_LOOP_BASE(uc);
847d5983e3SNicolas Saenz Julienne 
857d5983e3SNicolas Saenz Julienne     if (bc->init) {
867d5983e3SNicolas Saenz Julienne         bc->init(base, errp);
877d5983e3SNicolas Saenz Julienne     }
887d5983e3SNicolas Saenz Julienne }
897d5983e3SNicolas Saenz Julienne 
event_loop_base_can_be_deleted(UserCreatable * uc)9070ac26b9SNicolas Saenz Julienne static bool event_loop_base_can_be_deleted(UserCreatable *uc)
9170ac26b9SNicolas Saenz Julienne {
9270ac26b9SNicolas Saenz Julienne     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
9370ac26b9SNicolas Saenz Julienne     EventLoopBase *backend = EVENT_LOOP_BASE(uc);
9470ac26b9SNicolas Saenz Julienne 
9570ac26b9SNicolas Saenz Julienne     if (bc->can_be_deleted) {
9670ac26b9SNicolas Saenz Julienne         return bc->can_be_deleted(backend);
9770ac26b9SNicolas Saenz Julienne     }
9870ac26b9SNicolas Saenz Julienne 
9970ac26b9SNicolas Saenz Julienne     return true;
10070ac26b9SNicolas Saenz Julienne }
10170ac26b9SNicolas Saenz Julienne 
event_loop_base_class_init(ObjectClass * klass,void * class_data)1027d5983e3SNicolas Saenz Julienne static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
1037d5983e3SNicolas Saenz Julienne {
1047d5983e3SNicolas Saenz Julienne     UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
1057d5983e3SNicolas Saenz Julienne     ucc->complete = event_loop_base_complete;
10670ac26b9SNicolas Saenz Julienne     ucc->can_be_deleted = event_loop_base_can_be_deleted;
1077d5983e3SNicolas Saenz Julienne 
1087d5983e3SNicolas Saenz Julienne     object_class_property_add(klass, "aio-max-batch", "int",
1097d5983e3SNicolas Saenz Julienne                               event_loop_base_get_param,
1107d5983e3SNicolas Saenz Julienne                               event_loop_base_set_param,
1117d5983e3SNicolas Saenz Julienne                               NULL, &aio_max_batch_info);
112*71ad4713SNicolas Saenz Julienne     object_class_property_add(klass, "thread-pool-min", "int",
113*71ad4713SNicolas Saenz Julienne                               event_loop_base_get_param,
114*71ad4713SNicolas Saenz Julienne                               event_loop_base_set_param,
115*71ad4713SNicolas Saenz Julienne                               NULL, &thread_pool_min_info);
116*71ad4713SNicolas Saenz Julienne     object_class_property_add(klass, "thread-pool-max", "int",
117*71ad4713SNicolas Saenz Julienne                               event_loop_base_get_param,
118*71ad4713SNicolas Saenz Julienne                               event_loop_base_set_param,
119*71ad4713SNicolas Saenz Julienne                               NULL, &thread_pool_max_info);
1207d5983e3SNicolas Saenz Julienne }
1217d5983e3SNicolas Saenz Julienne 
1227d5983e3SNicolas Saenz Julienne static const TypeInfo event_loop_base_info = {
1237d5983e3SNicolas Saenz Julienne     .name = TYPE_EVENT_LOOP_BASE,
1247d5983e3SNicolas Saenz Julienne     .parent = TYPE_OBJECT,
1257d5983e3SNicolas Saenz Julienne     .instance_size = sizeof(EventLoopBase),
126*71ad4713SNicolas Saenz Julienne     .instance_init = event_loop_base_instance_init,
1277d5983e3SNicolas Saenz Julienne     .class_size = sizeof(EventLoopBaseClass),
1287d5983e3SNicolas Saenz Julienne     .class_init = event_loop_base_class_init,
1297d5983e3SNicolas Saenz Julienne     .abstract = true,
1307d5983e3SNicolas Saenz Julienne     .interfaces = (InterfaceInfo[]) {
1317d5983e3SNicolas Saenz Julienne         { TYPE_USER_CREATABLE },
1327d5983e3SNicolas Saenz Julienne         { }
1337d5983e3SNicolas Saenz Julienne     }
1347d5983e3SNicolas Saenz Julienne };
1357d5983e3SNicolas Saenz Julienne 
register_types(void)1367d5983e3SNicolas Saenz Julienne static void register_types(void)
1377d5983e3SNicolas Saenz Julienne {
1387d5983e3SNicolas Saenz Julienne     type_register_static(&event_loop_base_info);
1397d5983e3SNicolas Saenz Julienne }
1407d5983e3SNicolas Saenz Julienne type_init(register_types);
141