event-loop-base.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  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. #include "qemu/osdep.h"
  14. #include "qom/object_interfaces.h"
  15. #include "qapi/error.h"
  16. #include "block/thread-pool.h"
  17. #include "sysemu/event-loop-base.h"
  18. typedef struct {
  19. const char *name;
  20. ptrdiff_t offset; /* field's byte offset in EventLoopBase struct */
  21. } EventLoopBaseParamInfo;
  22. static void event_loop_base_instance_init(Object *obj)
  23. {
  24. EventLoopBase *base = EVENT_LOOP_BASE(obj);
  25. base->thread_pool_max = THREAD_POOL_MAX_THREADS_DEFAULT;
  26. }
  27. static EventLoopBaseParamInfo aio_max_batch_info = {
  28. "aio-max-batch", offsetof(EventLoopBase, aio_max_batch),
  29. };
  30. static EventLoopBaseParamInfo thread_pool_min_info = {
  31. "thread-pool-min", offsetof(EventLoopBase, thread_pool_min),
  32. };
  33. static EventLoopBaseParamInfo thread_pool_max_info = {
  34. "thread-pool-max", offsetof(EventLoopBase, thread_pool_max),
  35. };
  36. static void event_loop_base_get_param(Object *obj, Visitor *v,
  37. const char *name, void *opaque, Error **errp)
  38. {
  39. EventLoopBase *event_loop_base = EVENT_LOOP_BASE(obj);
  40. EventLoopBaseParamInfo *info = opaque;
  41. int64_t *field = (void *)event_loop_base + info->offset;
  42. visit_type_int64(v, name, field, errp);
  43. }
  44. static void event_loop_base_set_param(Object *obj, Visitor *v,
  45. const char *name, void *opaque, Error **errp)
  46. {
  47. EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(obj);
  48. EventLoopBase *base = EVENT_LOOP_BASE(obj);
  49. EventLoopBaseParamInfo *info = opaque;
  50. int64_t *field = (void *)base + info->offset;
  51. int64_t value;
  52. if (!visit_type_int64(v, name, &value, errp)) {
  53. return;
  54. }
  55. if (value < 0) {
  56. error_setg(errp, "%s value must be in range [0, %" PRId64 "]",
  57. info->name, INT64_MAX);
  58. return;
  59. }
  60. *field = value;
  61. if (bc->update_params) {
  62. bc->update_params(base, errp);
  63. }
  64. return;
  65. }
  66. static void event_loop_base_complete(UserCreatable *uc, Error **errp)
  67. {
  68. EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
  69. EventLoopBase *base = EVENT_LOOP_BASE(uc);
  70. if (bc->init) {
  71. bc->init(base, errp);
  72. }
  73. }
  74. static bool event_loop_base_can_be_deleted(UserCreatable *uc)
  75. {
  76. EventLoopBaseClass *bc = EVENT_LOOP_BASE_GET_CLASS(uc);
  77. EventLoopBase *backend = EVENT_LOOP_BASE(uc);
  78. if (bc->can_be_deleted) {
  79. return bc->can_be_deleted(backend);
  80. }
  81. return true;
  82. }
  83. static void event_loop_base_class_init(ObjectClass *klass, void *class_data)
  84. {
  85. UserCreatableClass *ucc = USER_CREATABLE_CLASS(klass);
  86. ucc->complete = event_loop_base_complete;
  87. ucc->can_be_deleted = event_loop_base_can_be_deleted;
  88. object_class_property_add(klass, "aio-max-batch", "int",
  89. event_loop_base_get_param,
  90. event_loop_base_set_param,
  91. NULL, &aio_max_batch_info);
  92. object_class_property_add(klass, "thread-pool-min", "int",
  93. event_loop_base_get_param,
  94. event_loop_base_set_param,
  95. NULL, &thread_pool_min_info);
  96. object_class_property_add(klass, "thread-pool-max", "int",
  97. event_loop_base_get_param,
  98. event_loop_base_set_param,
  99. NULL, &thread_pool_max_info);
  100. }
  101. static const TypeInfo event_loop_base_info = {
  102. .name = TYPE_EVENT_LOOP_BASE,
  103. .parent = TYPE_OBJECT,
  104. .instance_size = sizeof(EventLoopBase),
  105. .instance_init = event_loop_base_instance_init,
  106. .class_size = sizeof(EventLoopBaseClass),
  107. .class_init = event_loop_base_class_init,
  108. .abstract = true,
  109. .interfaces = (InterfaceInfo[]) {
  110. { TYPE_USER_CREATABLE },
  111. { }
  112. }
  113. };
  114. static void register_types(void)
  115. {
  116. type_register_static(&event_loop_base_info);
  117. }
  118. type_init(register_types);