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 "sysemu/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    return;
  78}
  79
  80static 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
  90static 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
 102static 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;
 106    ucc->can_be_deleted = event_loop_base_can_be_deleted;
 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);
 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);
 120}
 121
 122static const TypeInfo event_loop_base_info = {
 123    .name = TYPE_EVENT_LOOP_BASE,
 124    .parent = TYPE_OBJECT,
 125    .instance_size = sizeof(EventLoopBase),
 126    .instance_init = event_loop_base_instance_init,
 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
 136static void register_types(void)
 137{
 138    type_register_static(&event_loop_base_info);
 139}
 140type_init(register_types);
 141