qemu/event-loop-base.c
<<
>>
Prefs
   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"
  17#include "block/thread-pool.h"
  18#include "system/event-loop-base.h"
  19
  20typedef struct {
  21    const char *name;
  22    ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
  23} EventLoopBaseParamInfo;
  24
  25static 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
  32static EventLoopBaseParamInfo aio_max_batch_info = {
  33    "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
  34};
  35static EventLoopBaseParamInfo thread_pool_min_info = {
  36    "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
  37};
  38static EventLoopBaseParamInfo thread_pool_max_info = {
  39    "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
  40};
  41
  42static 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
  52static 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
  78static void event_loop_base_complete(UserCreatable *uc, Error **errp)
  79{
  80    EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
  81    EventLoopBase *base = EVENT_LOOP_BASE(uc);
  82
  83    if (bc->init) {
  84        bc->init(base, errp);
  85    }
  86}
  87
  88static bool event_loop_base_can_be_deleted(UserCreatable *uc)
  89{
  90    EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
  91    EventLoopBase *backend = EVENT_LOOP_BASE(uc);
  92
  93    if (bc->can_be_deleted) {
  94        return bc->can_be_deleted(backend);
  95    }
  96
  97    return true;
  98}
  99
 100static void event_loop_base_class_init(ObjectClass *klass,
 101                                       const void *class_data)
 102{
 103    UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
 104    ucc->complete = event_loop_base_complete;
 105    ucc->can_be_deleted = event_loop_base_can_be_deleted;
 106
 107    object_class_property_add(klass, "aio-max-batch", "int",
 108                              event_loop_base_get_param,
 109                              event_loop_base_set_param,
 110                              NULL, &aio_max_batch_info);
 111    object_class_property_add(klass, "thread-pool-min", "int",
 112                              event_loop_base_get_param,
 113                              event_loop_base_set_param,
 114                              NULL, &thread_pool_min_info);
 115    object_class_property_add(klass, "thread-pool-max", "int",
 116                              event_loop_base_get_param,
 117                              event_loop_base_set_param,
 118                              NULL, &thread_pool_max_info);
 119}
 120
 121static const TypeInfo event_loop_base_info = {
 122    .name = TYPE_EVENT_LOOP_BASE,
 123    .parent = TYPE_OBJECT,
 124    .instance_size = sizeof(EventLoopBase),
 125    .instance_init = event_loop_base_instance_init,
 126    .class_size = sizeof(EventLoopBaseClass),
 127    .class_init = event_loop_base_class_init,
 128    .abstract = true,
 129    .interfaces = (const InterfaceInfo[]) {
 130        { TYPE_USER_CREATABLE },
 131        { }
 132    }
 133};
 134
 135static void register_types(void)
 136{
 137    type_register_static(&event_loop_base_info);
 138}
 139type_init(register_types);
 140