]>
Commit | Line | Data |
---|---|---|
7d5983e3 NSJ |
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" | |
71ad4713 | 17 | #include "block/thread-pool.h" |
7d5983e3 NSJ |
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 | ||
71ad4713 NSJ |
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 | ||
7d5983e3 NSJ |
32 | static EventLoopBaseParamInfo aio_max_batch_info = { |
33 | "aio-max-batch", offsetof(EventLoopBase, aio_max_batch), | |
34 | }; | |
71ad4713 NSJ |
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 | }; | |
7d5983e3 NSJ |
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 | ||
70ac26b9 NSJ |
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 | ||
7d5983e3 NSJ |
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; | |
70ac26b9 | 106 | ucc->can_be_deleted = event_loop_base_can_be_deleted; |
7d5983e3 NSJ |
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); | |
71ad4713 NSJ |
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); | |
7d5983e3 NSJ |
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), | |
71ad4713 | 126 | .instance_init = event_loop_base_instance_init, |
7d5983e3 NSJ |
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); |