QEMU源码全解析24 —— QOM介绍(13)

88 篇文章 19 订阅
本文继续探讨QEMU QOM,重点在于属性的介绍。属性是QOM中管理对象的关键,分为类属性和对象属性,两者都以哈希表形式存储属性名与ObjectProperty的映射。属性对于设备状态的管理至关重要,如设置realized属性为true使设备变得可用。
摘要由CSDN通过智能技术生成

接前一篇文章: QEMU源码全解析23 —— QOM介绍(12)

本文内容参考:

《趣谈 Linux操作系统 》 —— 刘超, 极客时间

QEMU /KVM》源码解析与应用 —— 李强,机械工业出版社

特此致谢!

前文依次讲解了 QEMU QOM的三部分:类型的构造(类型的注册)、类型的初始化、类对象的构造(对象的初始化)。虽然过程比较曲折复杂,但到这一步也只是构造出了对象并且调用了对象的初始化函数而已。但是,EduState中的数据并没有填充,此时的edu设备的状态并不是可用的。对设备而言,还需要设置其realized属性为true(真)才行。由此引出来本回的题目—— 属性。

属性

QOM实现了类似于C++的基于类的多态,一个对象按照继承体系,可以是Object、DeviceState、PCIDevice等等。在QOM中为了便于管理对象,还为每种类型以及对象增加了属性。类属性存在于ObjectClass的properties域中,这个域是在类型初始化函数type_initialize中构造的。

为了便于理解,再次贴出include/qom/object.h中ObjectClass类的定义、qom/object.c中TypeImpl的定义以及qom/object.c中的type_initialize函数:

  1. /**
  2. * struct ObjectClass:
  3. *
  4. * The base for all classes. The only thing that #ObjectClass contains is an
  5. * integer type handle.
  6. */
  7. struct ObjectClass
  8. {
  9. /* private: */
  10. Type type;
  11. GSList *interfaces;
  12. const char *object_cast_cache[OBJECT_CLASS_CAST_CACHE];
  13. const char *class_cast_cache[OBJECT_CLASS_CAST_CACHE];
  14. ObjectUnparent *unparent;
  15. GHashTable *properties;
  16. };
  1. struct TypeImpl
  2. {
  3. const char *name;
  4. size_t class_size;
  5. size_t instance_size;
  6. size_t instance_align;
  7. void (*class_init)(ObjectClass *klass, void *data);
  8. void (*class_base_init)(ObjectClass *klass, void *data);
  9. void *class_data;
  10. void (*instance_init)(Object *obj);
  11. void (*instance_post_init)(Object *obj);
  12. void (*instance_finalize)(Object *obj);
  13. bool abstract;
  14. const char *parent;
  15. TypeImpl *parent_type;
  16. ObjectClass *class;
  17. int num_interfaces;
  18. InterfaceImpl interfaces[MAX_INTERFACES];
  19. };
  1. static void type_initialize(TypeImpl *ti)
  2. {
  3. TypeImpl *parent;
  4. if (ti->class) {
  5. return;
  6. }
  7. ti->class_size = type_class_get_size(ti);
  8. ti->instance_size = type_object_get_size(ti);
  9. /* Any type with zero instance_size is implicitly abstract.
  10. * This means interface types are all abstract.
  11. */
  12. if (ti->instance_size == 0) {
  13. ti->abstract = true;
  14. }
  15. if (type_is_ancestor(ti, type_interface)) {
  16. assert(ti->instance_size == 0);
  17. assert(ti->abstract);
  18. assert(!ti->instance_init);
  19. assert(!ti->instance_post_init);
  20. assert(!ti->instance_finalize);
  21. assert(!ti->num_interfaces);
  22. }
  23. ti->class = g_malloc0(ti->class_size);
  24. parent = type_get_parent(ti);
  25. if (parent) {
  26. type_initialize(parent);
  27. GSList *e;
  28. int i;
  29. g_assert(parent->class_size <= ti->class_size);
  30. g_assert(parent->instance_size <= ti->instance_size);
  31. memcpy(ti->class, parent->class, parent->class_size);
  32. ti->class->interfaces = NULL;
  33. for (e = parent->class->interfaces; e; e = e->next) {
  34. InterfaceClass *iface = e->data;
  35. ObjectClass *klass = OBJECT_CLASS(iface);
  36. type_initialize_interface(ti, iface->interface_type, klass->type);
  37. }
  38. for (i = 0; i < ti->num_interfaces; i++) {
  39. TypeImpl *t = type_get_by_name(ti->interfaces[i].typename);
  40. if (!t) {
  41. error_report("missing interface '%s' for object '%s'",
  42. ti->interfaces[i].typename, parent->name);
  43. abort();
  44. }
  45. for (e = ti->class->interfaces; e; e = e->next) {
  46. TypeImpl *target_type = OBJECT_CLASS(e->data)->type;
  47. if (type_is_ancestor(target_type, t)) {
  48. break;
  49. }
  50. }
  51. if (e) {
  52. continue;
  53. }
  54. type_initialize_interface(ti, t, t);
  55. }
  56. }
  57. ti->class->properties = g_hash_table_new_full(g_str_hash, g_str_equal, NULL,
  58. object_property_free);
  59. ti->class->type = ti;
  60. while (parent) {
  61. if (parent->class_base_init) {
  62. parent->class_base_init(ti->class, ti->class_data);
  63. }
  64. parent = type_get_parent(parent);
  65. }
  66. if (ti->class_init) {
  67. ti->class_init(ti->class, ti->class_data);
  68. }
  69. }

对象属性存放在Object的properties域中,这个域是在对象的初始化函数ubject_initialize_with_type中构造的。

为了便于理解,再次贴出include/qom/object.h中Object类的定义以及qom/object.c中的type_initialize函数:

  1. /**
  2. * struct Object:
  3. *
  4. * The base for all objects. The first member of this object is a pointer to
  5. * a #ObjectClass. Since C guarantees that the first member of a structure
  6. * always begins at byte 0 of that structure, as long as any sub-object places
  7. * its parent as the first member, we can cast directly to a #Object.
  8. *
  9. * As a result, #Object contains a reference to the objects type as its
  10. * first member. This allows identification of the real type of the object at
  11. * run time.
  12. */
  13. struct Object
  14. {
  15. /* private: */
  16. ObjectClass *class;
  17. ObjectFree *free;
  18. GHashTable *properties;
  19. uint32_t ref;
  20. Object *parent;
  21. };
  1. static void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
  2. {
  3. type_initialize(type);
  4. g_assert(type->instance_size >= sizeof(Object));
  5. g_assert(type->abstract == false);
  6. g_assert(size >= type->instance_size);
  7. memset(obj, 0, type->instance_size);
  8. obj->class = type->class;
  9. object_ref(obj);
  10. object_class_property_init_all(obj);
  11. obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
  12. NULL, object_property_free);
  13. object_init_with_type(obj, type);
  14. object_post_init_with_type(obj, type);
  15. }

类的属性和对象的属性都为GHashTable类型,即两者皆为一个哈希表,在表中存着属性名到ObjectProperty的映射。

属性由ObjectProperty表示。下一回对其做深入讲解。

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他