Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 1 | /* |
| 2 | * QEMU event-loop base |
| 3 | * |
| 4 | * Copyright (C) 2022 Red Hat Inc |
| 5 | * |
| 6 | * Authors: |
| 7 | * Stefan Hajnoczi <stefanha@redhat.com> |
| 8 | * Nicolas Saenz Julienne <nsaenzju@redhat.com> |
| 9 | * |
| 10 | * This work is licensed under the terms of the GNU GPL, version 2 or later. |
| 11 | * See the COPYING file in the top-level directory. |
| 12 | */ |
| 13 | |
| 14 | #include "qemu/osdep.h" |
| 15 | #include "qom/object_interfaces.h" |
| 16 | #include "qapi/error.h" |
Nicolas Saenz Julienne | 71ad471 | 2022-04-25 09:57:23 +0200 | [diff] [blame] | 17 | #include "block/thread-pool.h" |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 18 | #include "sysemu/event-loop-base.h" |
| 19 | |
| 20 | typedef struct { |
| 21 | const char *name; |
| 22 | ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */ |
| 23 | } EventLoopBaseParamInfo; |
| 24 | |
Nicolas Saenz Julienne | 71ad471 | 2022-04-25 09:57:23 +0200 | [diff] [blame] | 25 | static void event_loop_base_instance_init(Object *obj) |
| 26 | { |
| 27 | EventLoopBase *base = EVENT_LOOP_BASE(obj); |
| 28 | |
| 29 | base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT; |
| 30 | } |
| 31 | |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 32 | static EventLoopBaseParamInfo aio_max_batch_info = { |
| 33 | "aio-max-batch", offsetof(EventLoopBase, aio_max_batch), |
| 34 | }; |
Nicolas Saenz Julienne | 71ad471 | 2022-04-25 09:57:23 +0200 | [diff] [blame] | 35 | static EventLoopBaseParamInfo thread_pool_min_info = { |
| 36 | "thread-pool-min", offsetof(EventLoopBase, thread_pool_min), |
| 37 | }; |
| 38 | static EventLoopBaseParamInfo thread_pool_max_info = { |
| 39 | "thread-pool-max", offsetof(EventLoopBase, thread_pool_max), |
| 40 | }; |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 41 | |
| 42 | static void event_loop_base_get_param(Object *obj, Visitor *v, |
| 43 | const char *name, void *opaque, Error **errp) |
| 44 | { |
| 45 | EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj); |
| 46 | EventLoopBaseParamInfo *info = opaque; |
| 47 | int64_t *field = (void *)event_loop_base + info->offset; |
| 48 | |
| 49 | visit_type_int64(v, name, field, errp); |
| 50 | } |
| 51 | |
| 52 | static void event_loop_base_set_param(Object *obj, Visitor *v, |
| 53 | const char *name, void *opaque, Error **errp) |
| 54 | { |
| 55 | EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj); |
| 56 | EventLoopBase *base = EVENT_LOOP_BASE(obj); |
| 57 | EventLoopBaseParamInfo *info = opaque; |
| 58 | int64_t *field = (void *)base + info->offset; |
| 59 | int64_t value; |
| 60 | |
| 61 | if (!visit_type_int64(v, name, &value, errp)) { |
| 62 | return; |
| 63 | } |
| 64 | |
| 65 | if (value < 0) { |
| 66 | error_setg(errp, "%s value must be in range [0, %" PRId64 "]", |
| 67 | info->name, INT64_MAX); |
| 68 | return; |
| 69 | } |
| 70 | |
| 71 | *field = value; |
| 72 | |
| 73 | if (bc->update_params) { |
| 74 | bc->update_params(base, errp); |
| 75 | } |
| 76 | |
| 77 | return; |
| 78 | } |
| 79 | |
| 80 | static void event_loop_base_complete(UserCreatable *uc, Error **errp) |
| 81 | { |
| 82 | EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc); |
| 83 | EventLoopBase *base = EVENT_LOOP_BASE(uc); |
| 84 | |
| 85 | if (bc->init) { |
| 86 | bc->init(base, errp); |
| 87 | } |
| 88 | } |
| 89 | |
Nicolas Saenz Julienne | 70ac26b | 2022-04-25 09:57:22 +0200 | [diff] [blame] | 90 | static bool event_loop_base_can_be_deleted(UserCreatable *uc) |
| 91 | { |
| 92 | EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc); |
| 93 | EventLoopBase *backend = EVENT_LOOP_BASE(uc); |
| 94 | |
| 95 | if (bc->can_be_deleted) { |
| 96 | return bc->can_be_deleted(backend); |
| 97 | } |
| 98 | |
| 99 | return true; |
| 100 | } |
| 101 | |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 102 | static void event_loop_base_class_init(ObjectClass *klass, void *class_data) |
| 103 | { |
| 104 | UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass); |
| 105 | ucc->complete = event_loop_base_complete; |
Nicolas Saenz Julienne | 70ac26b | 2022-04-25 09:57:22 +0200 | [diff] [blame] | 106 | ucc->can_be_deleted = event_loop_base_can_be_deleted; |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 107 | |
| 108 | object_class_property_add(klass, "aio-max-batch", "int", |
| 109 | event_loop_base_get_param, |
| 110 | event_loop_base_set_param, |
| 111 | NULL, &aio_max_batch_info); |
Nicolas Saenz Julienne | 71ad471 | 2022-04-25 09:57:23 +0200 | [diff] [blame] | 112 | object_class_property_add(klass, "thread-pool-min", "int", |
| 113 | event_loop_base_get_param, |
| 114 | event_loop_base_set_param, |
| 115 | NULL, &thread_pool_min_info); |
| 116 | object_class_property_add(klass, "thread-pool-max", "int", |
| 117 | event_loop_base_get_param, |
| 118 | event_loop_base_set_param, |
| 119 | NULL, &thread_pool_max_info); |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 120 | } |
| 121 | |
| 122 | static const TypeInfo event_loop_base_info = { |
| 123 | .name = TYPE_EVENT_LOOP_BASE, |
| 124 | .parent = TYPE_OBJECT, |
| 125 | .instance_size = sizeof(EventLoopBase), |
Nicolas Saenz Julienne | 71ad471 | 2022-04-25 09:57:23 +0200 | [diff] [blame] | 126 | .instance_init = event_loop_base_instance_init, |
Nicolas Saenz Julienne | 7d5983e | 2022-04-25 09:57:21 +0200 | [diff] [blame] | 127 | .class_size = sizeof(EventLoopBaseClass), |
| 128 | .class_init = event_loop_base_class_init, |
| 129 | .abstract = true, |
| 130 | .interfaces = (InterfaceInfo[]) { |
| 131 | { TYPE_USER_CREATABLE }, |
| 132 | { } |
| 133 | } |
| 134 | }; |
| 135 | |
| 136 | static void register_types(void) |
| 137 | { |
| 138 | type_register_static(&event_loop_base_info); |
| 139 | } |
| 140 | type_init(register_types); |