xref: /qemu/event-loop-base.c (revision 06b40d250ecfa1633209c2e431a7a38acfd03a98)
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"
1771ad4713SNicolas Saenz Julienne #include "block/thread-pool.h"
1832cad1ffSPhilippe Mathieu-Daudé #include "system/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)2571ad4713SNicolas Saenz Julienne static void event_loop_base_instance_init(Object *obj)
2671ad4713SNicolas Saenz Julienne {
2771ad4713SNicolas Saenz Julienne     EventLoopBase *base = EVENT_LOOP_BASE(obj);
2871ad4713SNicolas Saenz Julienne 
2971ad4713SNicolas Saenz Julienne     base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
3071ad4713SNicolas Saenz Julienne }
3171ad4713SNicolas 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 };
3571ad4713SNicolas Saenz Julienne static EventLoopBaseParamInfo thread_pool_min_info = {
3671ad4713SNicolas Saenz Julienne     "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
3771ad4713SNicolas Saenz Julienne };
3871ad4713SNicolas Saenz Julienne static EventLoopBaseParamInfo thread_pool_max_info = {
3971ad4713SNicolas Saenz Julienne     "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
4071ad4713SNicolas 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 
event_loop_base_complete(UserCreatable * uc,Error ** errp)787d5983e3SNicolas Saenz Julienne static void event_loop_base_complete(UserCreatable *uc, Error **errp)
797d5983e3SNicolas Saenz Julienne {
807d5983e3SNicolas Saenz Julienne     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
817d5983e3SNicolas Saenz Julienne     EventLoopBase *base = EVENT_LOOP_BASE(uc);
827d5983e3SNicolas Saenz Julienne 
837d5983e3SNicolas Saenz Julienne     if (bc->init) {
847d5983e3SNicolas Saenz Julienne         bc->init(base, errp);
857d5983e3SNicolas Saenz Julienne     }
867d5983e3SNicolas Saenz Julienne }
877d5983e3SNicolas Saenz Julienne 
event_loop_base_can_be_deleted(UserCreatable * uc)8870ac26b9SNicolas Saenz Julienne static bool event_loop_base_can_be_deleted(UserCreatable *uc)
8970ac26b9SNicolas Saenz Julienne {
9070ac26b9SNicolas Saenz Julienne     EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
9170ac26b9SNicolas Saenz Julienne     EventLoopBase *backend = EVENT_LOOP_BASE(uc);
9270ac26b9SNicolas Saenz Julienne 
9370ac26b9SNicolas Saenz Julienne     if (bc->can_be_deleted) {
9470ac26b9SNicolas Saenz Julienne         return bc->can_be_deleted(backend);
9570ac26b9SNicolas Saenz Julienne     }
9670ac26b9SNicolas Saenz Julienne 
9770ac26b9SNicolas Saenz Julienne     return true;
9870ac26b9SNicolas Saenz Julienne }
9970ac26b9SNicolas Saenz Julienne 
event_loop_base_class_init(ObjectClass * klass,const void * class_data)10012d1a768SPhilippe Mathieu-Daudé static void event_loop_base_class_init(ObjectClass *klass,
10112d1a768SPhilippe Mathieu-Daudé                                        const void *class_data)
1027d5983e3SNicolas Saenz Julienne {
1037d5983e3SNicolas Saenz Julienne     UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
1047d5983e3SNicolas Saenz Julienne     ucc->complete = event_loop_base_complete;
10570ac26b9SNicolas Saenz Julienne     ucc->can_be_deleted = event_loop_base_can_be_deleted;
1067d5983e3SNicolas Saenz Julienne 
1077d5983e3SNicolas Saenz Julienne     object_class_property_add(klass, "aio-max-batch", "int",
1087d5983e3SNicolas Saenz Julienne                               event_loop_base_get_param,
1097d5983e3SNicolas Saenz Julienne                               event_loop_base_set_param,
1107d5983e3SNicolas Saenz Julienne                               NULL, &aio_max_batch_info);
11171ad4713SNicolas Saenz Julienne     object_class_property_add(klass, "thread-pool-min", "int",
11271ad4713SNicolas Saenz Julienne                               event_loop_base_get_param,
11371ad4713SNicolas Saenz Julienne                               event_loop_base_set_param,
11471ad4713SNicolas Saenz Julienne                               NULL, &thread_pool_min_info);
11571ad4713SNicolas Saenz Julienne     object_class_property_add(klass, "thread-pool-max", "int",
11671ad4713SNicolas Saenz Julienne                               event_loop_base_get_param,
11771ad4713SNicolas Saenz Julienne                               event_loop_base_set_param,
11871ad4713SNicolas Saenz Julienne                               NULL, &thread_pool_max_info);
1197d5983e3SNicolas Saenz Julienne }
1207d5983e3SNicolas Saenz Julienne 
1217d5983e3SNicolas Saenz Julienne static const TypeInfo event_loop_base_info = {
1227d5983e3SNicolas Saenz Julienne     .name = TYPE_EVENT_LOOP_BASE,
1237d5983e3SNicolas Saenz Julienne     .parent = TYPE_OBJECT,
1247d5983e3SNicolas Saenz Julienne     .instance_size = sizeof(EventLoopBase),
12571ad4713SNicolas Saenz Julienne     .instance_init = event_loop_base_instance_init,
1267d5983e3SNicolas Saenz Julienne     .class_size = sizeof(EventLoopBaseClass),
1277d5983e3SNicolas Saenz Julienne     .class_init = event_loop_base_class_init,
1287d5983e3SNicolas Saenz Julienne     .abstract = true,
129*2cd09e47SPhilippe Mathieu-Daudé     .interfaces = (const InterfaceInfo[]) {
1307d5983e3SNicolas Saenz Julienne         { TYPE_USER_CREATABLE },
1317d5983e3SNicolas Saenz Julienne         { }
1327d5983e3SNicolas Saenz Julienne     }
1337d5983e3SNicolas Saenz Julienne };
1347d5983e3SNicolas Saenz Julienne 
register_types(void)1357d5983e3SNicolas Saenz Julienne static void register_types(void)
1367d5983e3SNicolas Saenz Julienne {
1377d5983e3SNicolas Saenz Julienne     type_register_static(&event_loop_base_info);
1387d5983e3SNicolas Saenz Julienne }
1397d5983e3SNicolas Saenz Julienne type_init(register_types);
140