接前一篇文章: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中,代码如下:
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));
}
}
本回就讲到这里,下一回结合一个实例再次对此流程进行解析。