接前一篇文章: QEMU源码全解析 —— 块设备虚拟化(10)
本文内容参考:
《趣谈 Linux操作系统 》 —— 刘超,极客时间
《 QEMU /KVM源码解析与应用》 —— 李强,机械工业出版社
C函数学习(2):GLib HashTable函数_glib 哈希表-CSDN博客
特此致谢!
QEMU初始化阶段的块设备虚拟化
从模板生成类和类的实例化
本回继续解析QEMU类Java反射机制的整个流程。
在QEMU中,每一个Module回模拟某种设备,那么就定义一种类型TypeImpl来表示此种设备。
完整的函数调用链为:
type_init()
---> type_register_static()
---> type_register()
---> type_register_internal()
---> type_new()
---> type_table_add()
上一回解析完了type_register_internal函数中的type_new函数,接下来该调用type_table_add函数了。为了便于理解和回顾,再次贴出type_register_internal函数源码,在qom/object.c中,如下:
static TypeImpl *type_register_internal(const TypeInfo *info)
{
TypeImpl *ti;
ti = type_new(info);
type_table_add(ti);
return ti;
}
前文书已讲过:
type_new函数已经将TypeInfo virtio_blk_info中的信息赋给了函数中新建(调用g_malloc0()动态创建)的TypeImpl对象,并使ti指向了这段内存。接下来就是调用type_table_add函数,将这个对象添加(插入)到全局表type_table中。
type_table_add函数也在qom/object.c中,代码如下:
static void type_table_add(TypeImpl *ti)
{
assert(!enumerating_types);
g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
}
type_table_lookup()之前在type_new函数中也遇到过,也在qom/object.c中,代码如下:
static GHashTable *type_table_get(void)
{
static GHashTable *type_table;
if (type_table == NULL) {
type_table = g_hash_table_new(g_str_hash, g_str_equal);
}
return type_table;
}
type_table_get函数比较简单易懂,如果type_table为NULL即之前没有创建过,那么就调用g_hash_table_new函数进行创建。之后再调用此函数时,就直接返回创建的type_teble了。
g_hash_table_new函数用于创建一个hash表;g_hash_table_insert函数用于向(创建的)hash表中插入条目,插入的条目必须是一个key-value对。
这里,key对应的是(void *)ti->name,而value对应的是ti本身。
至此,由TypeImpl已经创建了类。但类初始化class_init(本例中是virtio_blk_class_init)函数还没有被调用,这个类还处于纸面的状态(type_init函数用于注册类。每一层都有class_init,用于从TypeImpl生产xxxClass)。到此也就相当于Java反射中的第1步。
流程中的更多步骤,请看下回。