QEMU源码全解析22 —— QOM介绍(11)

88 篇文章 19 订阅
本文详细解析QEMU源码中`object_initialize_with_type`函数,从device_init_func函数的调用链开始,探讨QOM(对象模型)在QEMU中的作用。内容涉及`object_new_with_type`、`object_init_with_type`和`object_post_init_with_type`函数,阐述这些函数如何初始化对象并调用相关初始化函数。
摘要由CSDN通过智能技术生成

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

本文内容参考:

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

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

特此致谢!

上回书说到由打device_init_func函数经过以下层层调用,最终来到了object_initialize_with_type函数。

device_init_func -> qdev_device_add -> qdev_device_add_from_qdict -> qdev_new ->

object_new -> object_new_with_type -> object_initialize_with_type -> object_init_with_type

本文对object_initialize_with_type函数进行深入解析。

object_init_with_type函数仍然在qom/object.c中,代码如下:

  1. static void object_init_with_type(Object *obj, TypeImpl *ti)
  2. {
  3. if (type_has_parent(ti)) {
  4. object_init_with_type(obj, type_get_parent(ti));
  5. }
  6. if (ti->instance_init) {
  7. ti->instance_init(obj);
  8. }
  9. }

简单来讲,object_new函数通过传进来的typename参数找到对应的TypeImpl,再调用object_new_with_type函数。为了便于理解和加深印象,再次贴出代码:

  1. bject *object_new(const char *typename)
  2. {
  3. TypeImpl *ti = type_get_by_name(typename);
  4. return object_new_with_type(ti);
  5. }

object_new_with_type函数首先调用type_initialize函数确保类型已经经过初始化,然后分配type->instance_size作为大小分配对象的实际空间,接着调用object_initialize_with_type对对象进行初始化。再次贴出代码如下:

  1. static Object *object_new_with_type(Type type)
  2. {
  3. Object *obj;
  4. size_t size, align;
  5. void (*obj_free)(void *);
  6. g_assert(type != NULL);
  7. type_initialize(type);
  8. size = type->instance_size;
  9. align = type->instance_align;
  10. /*
  11. * Do not use qemu_memalign unless required. Depending on the
  12. * implementation, extra alignment implies extra overhead.
  13. */
  14. if (likely(align <= __alignof__(qemu_max_align_t))) {
  15. obj = g_malloc(size);
  16. obj_free = g_free;
  17. } else {
  18. obj = qemu_memalign(align, size);
  19. obj_free = qemu_vfree;
  20. }
  21. object_initialize_with_type(obj, size, type);
  22. obj->free = obj_free;
  23. return obj;
  24. }

object_initialize_with_type函数的主要工作是对object_init_with_type和object_post_init_with_type函数进行调用。再次贴出代码如下:

  1. tatic 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. }

前者(object_init_with_type函数)通过递归,调用所有父类型的对象初始化函数和自身对象的初始化函数。再次贴出本回开头的代码:

  1. static void object_init_with_type(Object *obj, TypeImpl *ti)
  2. {
  3. if (type_has_parent(ti)) {
  4. object_init_with_type(obj, type_get_parent(ti));
  5. }
  6. if (ti->instance_init) {
  7. ti->instance_init(obj);
  8. }
  9. }

后者(object_post_init_with_type函数)调用TypeImpl的instance_post_init回调成员完成对象初始化之后的工作。object_post_init_with_type函数同样在qom/object.c中,代码如下:

  1. static void object_post_init_with_type(Object *obj, TypeImpl *ti)
  2. {
  3. if (ti->instance_post_init) {
  4. ti->instance_post_init(obj);
  5. }
  6. if (type_has_parent(ti)) {
  7. object_post_init_with_type(obj, type_get_parent(ti));
  8. }
  9. }

本回就讲到这里,下一回结合一个实例再次对此流程进行解析。

举报

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