接前一篇文章: QEMU源码全解析21 —— QOM介绍(10)
本文内容参考:
《 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中,代码如下:
- static void object_init_with_type(Object *obj, TypeImpl *ti)
- {
- if (type_has_parent(ti)) {
- object_init_with_type(obj, type_get_parent(ti));
- }
-
- if (ti->instance_init) {
- ti->instance_init(obj);
- }
- }
简单来讲,object_new函数通过传进来的typename参数找到对应的TypeImpl,再调用object_new_with_type函数。为了便于理解和加深印象,再次贴出代码:
- bject *object_new(const char *typename)
- {
- TypeImpl *ti = type_get_by_name(typename);
-
- return object_new_with_type(ti);
- }
object_new_with_type函数首先调用type_initialize函数确保类型已经经过初始化,然后分配type->instance_size作为大小分配对象的实际空间,接着调用object_initialize_with_type对对象进行初始化。再次贴出代码如下:
- static Object *object_new_with_type(Type type)
- {
- Object *obj;
- size_t size, align;
- void (*obj_free)(void *);
-
- g_assert(type != NULL);
- type_initialize(type);
-
- size = type->instance_size;
- align = type->instance_align;
-
- /*
- * Do not use qemu_memalign unless required. Depending on the
- * implementation, extra alignment implies extra overhead.
- */
- if (likely(align <= __alignof__(qemu_max_align_t))) {
- obj = g_malloc(size);
- obj_free = g_free;
- } else {
- obj = qemu_memalign(align, size);
- obj_free = qemu_vfree;
- }
-
- object_initialize_with_type(obj, size, type);
- obj->free = obj_free;
-
- return obj;
- }
-
object_initialize_with_type函数的主要工作是对object_init_with_type和object_post_init_with_type函数进行调用。再次贴出代码如下:
- tatic void object_initialize_with_type(Object *obj, size_t size, TypeImpl *type)
- {
- type_initialize(type);
-
- g_assert(type->instance_size >= sizeof(Object));
- g_assert(type->abstract == false);
- g_assert(size >= type->instance_size);
-
- memset(obj, 0, type->instance_size);
- obj->class = type->class;
- object_ref(obj);
- object_class_property_init_all(obj);
- obj->properties = g_hash_table_new_full(g_str_hash, g_str_equal,
- NULL, object_property_free);
- object_init_with_type(obj, type);
- object_post_init_with_type(obj, type);
- }
前者(object_init_with_type函数)通过递归,调用所有父类型的对象初始化函数和自身对象的初始化函数。再次贴出本回开头的代码:
- static void object_init_with_type(Object *obj, TypeImpl *ti)
- {
- if (type_has_parent(ti)) {
- object_init_with_type(obj, type_get_parent(ti));
- }
-
- if (ti->instance_init) {
- ti->instance_init(obj);
- }
- }
后者(object_post_init_with_type函数)调用TypeImpl的instance_post_init回调成员完成对象初始化之后的工作。object_post_init_with_type函数同样在qom/object.c中,代码如下:
- static void object_post_init_with_type(Object *obj, TypeImpl *ti)
- {
- if (ti->instance_post_init) {
- ti->instance_post_init(obj);
- }
-
- if (type_has_parent(ti)) {
- object_post_init_with_type(obj, type_get_parent(ti));
- }
- }
本回就讲到这里,下一回结合一个实例再次对此流程进行解析。