技术笔记:QOM模型初始化流程

简介: 技术笔记:QOM模型初始化流程

目录


3.1 、类型注册1.2 对象创建1.3 对象获取1.4 属性操作1.5 类型转换


Qemu Object Model


QOM (Qemu Object Model)是Qemu实现的面向对象编程模式。Qemu是用C语言编写的,而C语言是面向过程的编程语言,无法享受面向对象编程模式针对复杂软件系统在设计模式上的优越性。为解决该问题,Qemu社区通过C语言实现了一套面向对象的编程接口,即QOM,并成功将其应用在Qemu设备模型的管理中。


1、简介


QOM是一套创建“类”和“对象”的编程接口。这套接口也是一种支持用户创建类型并根据类型实例化对象的灵活框架,其具有以下特性:


支持动态注册并创建类型;


支持类型的单继承(仅有一个父类);


支持类型的多继承;


2、 一个简单应用实例


下面通过一个简单代码实例,先来了解QOM的基本使用方法。


#include "qdev.h"


#define TYPE_MY_DEVICE "my-device"


// No new virtual functions: we can reuse the typedef for the


// superclass.


typedef DeviceClass MyDeviceClass;


typedef struct MyDevice


{


DeviceState parent;


int reg0, reg1, reg2;


} MyDevice;


static const TypeInfo my_device_info = {


.name = TYPE_MY_DEVICE,


.parent = TYPE_DEVICE,


.instance_size = sizeof(MyDevice),


};


static void my_device_register_types(void)


{


type_register_static(&my_device_info);


}


type_init(my_device_register_types)


这个代码示例的功能是通过QOM接口(type_init, type_register_static)向QOM系统注册了一个TYPE_MY_DEVICE类型。该类型包含一个class类(结构) MyDeviceClass和一个object类(结构)MyDevice。class类包括一组函数指针,用来灵活指明调用函数;object类通常用来表达对象的属性信息。一个class类仅会实例化出一个class对象,而object类可以实例化出多个对象且每个对象都指向同一个class对象,如图1所示。其中ObjectClass和Object为QOM定义的基本结构,DeviceClass和DeviceState是Qemu为设备模型定义的基本结构。


图1. 示例类与对象关系图


从这个示例中还可以看出类型TYPE_MY_DEVICE的父类型是TYPE_DEVICE (见my_device_info中的parent字段),但是实际的父子关系是在具体的类型定义中体现的,如MyDevice中的第一个字段parent即是DeviceState类,MyDeviceClass和DeviceClass为同一结构。


3、QOM接口基本用法


总的来说,QOM提供的接口可分为五类:类型注册、对象创建、对象获取、属性操作和类型转换。


回到顶部3.1 、类型注册


TypeImpl type_register_static(const TypeInfo info);


该接口向QOM系统注册了一个由TypeInfo描述的类型。


struct TypeInfo{


const char name; //表示该类型的字符串名称;


const char parent; //表示该类型的父类型的字符串名称;


size_t instance_size; //该类型所能创建的object类对象的内存空间占用大小;如果该值为0,则使用父类的instance_size;


void (instance_init)(Object obj);//创建的object类对象的初始化函数;仅初始化该类型自身的成员属性,不包含父类型成员(通常父类型已经初始化完成);


void (instance_finalize)(Object obj);//创建的object类对象的析构函数;


bool abstract;//表示该类型是否为抽象类;抽象类不能实例化object类对象;


size_t class_size;//该类型所能创建的class类对象的内存空间占用大小;如果该值为0,则使用父类型的class_size;


void (class_init)(ObjectClass klass, void data);//创建的class类对象的初始化函数;仅初始化该类型自身的函数指针,不包含父类;


void (class_base_init)(ObjectClass klass, void data);//该函数在父类型的class类对象初始化完成后,在当前class类对象的class_init执行前被调用;


void (class_finalize)(ObjectClass klass, void data);//创建的class类对象的析构函数;


void class_data;//传递给class_init、class_base_init和class_finalize的参数;


InterfaceInfo interfaces;//该类型的接口列表;


};


回到顶部1.2 对象创建


Object object_new(const char typename);


该接口创建一个类型名为typename的object类对象。创建过程中,如果该类型对应的class类对象不存在,还会创建该class类对象并调用其class_init初始化;如果存在父类型,还会递归创建父类的class类对象并初始化。


Class类对象创建完成后,还会对当前object类对象执行父类和自身的instance_init函数。最终,对象初始化完成后,其引用计数为1。


Object object_new_with_type(Type type);


该接口功能同object_new,参数由字符名改为Type。


void object_initialize(void obj, const char typename);


该接口对已经存在的对象obj,按typename类型进行初始化操作。


Object object_dynamic_cast(Object obj, const char typename);


该接口将已经存在的对象obj强转成typename类型。


回到顶部1.3 对象获取


ObjectClass object_get_class(Object obj);


该接口获取obj对象的唯一class类对象。


const char object_get_typename(Object obj);


该接口获取obj对象的字符串类型名。


ObjectClass object_class_get_parent(ObjectClass klass);


该接口获取class对象klass的父类的class对象。


const char object_class_get_name(ObjectClass klass);


该接口获取class对象klass对应的类型的字符串名称


回到顶部1.4 属性操作


void object_property_add(Object //代码效果参考:http://www.jhylw.com.cn/100631107.html

obj, const char name, const char type,

ObjectPropertyAccessor get,


ObjectPropertyAccessor set,


ObjectPropertyRelease release,


void opaque, struct Error errp);


void object_property_del(Object obj, const char name, struct Error errp);


ObjectProperty object_property_find(Object obj, const char name,


struct Error **errp);


void object_property_get(Object obj, struct Visitor v, const char name,


struct Error errp);


void object_property_set(Object obj, struct Visitor v, const char *name,


struct Error errp);


void object_property_set_str(Object obj, const char value,


const //代码效果参考:http://www.jhylw.com.cn/570832983.html

char name, struct Error **errp);

char object_property_get_str(Object obj, const char name,


struct Error errp);


void object_property_set_link(Object obj, Object value,


const char *name, struct Error errp);


Object object_property_get_link(Object obj, const char name,


struct Error **errp);


void object_property_set_bool(Object obj, bool value,


const char name, struct Error **errp);


bool object_property_get_bool(Object obj, const char name,


struct Error **errp);


void object_property_set_int(Object obj, int64_t value,


const char name, struct Error **errp);


int64_t object_property_get_int(Object obj, const char name,


struct Error **errp);


void object_property_add_child(Object obj, const char name,


Object child, struct Error errp);


void object_property_add_link(Object obj, const char name,


const char *type, Object child,


struct Error errp);


回到顶部1.5 类型转换


#define OBJECT_CHECK(type, obj, name) \


((type )object_dynamic_cast_assert(OBJECT(obj), (name), \


FILE, LINE, func))


该宏将obj强转成type类型。


#define OBJECT_CLASS_CHECK(class, obj, name) \


((class )object_class_dynamic_cast_assert(OBJECT_CLASS(obj), (name), \


FILE, LINE, func))


该宏将obj强转成对应的class类对象。


4、Qemu设备模型


5、QOM设备初始化调用流程(virtio-balloon为例)


6. 数据结构组成:


7. QEMU侧QOM模型结构


8. 一个自建设备的初始化流程


1. 存储init执行函数


在main_impl执行之前,通过type_init将设备init执行函数存入全局数组init_type_listQOMQOMQOM,调用关系如下,参考流程图①:


c</p> <p>register_module_init(mydevice_register_types)</p> <p>->find_type(init_type_list【QOM】)->INSERT</p> <p>


2. 存储TypeInfo


main_impl中执行module_call_init, 遍历init_type_list中注册的QOM类型设备的执行函数,将TypeInfo转换为TypeImpl存储到全局hash表type_table。调用关系如下,参考流程图②:


c</p> <p>module_call_init(QOM) -> mydevice_register_types -> type_register_static -> type_table_add(TypeInfo->TypeImpl) -> g_hash_table_insert(type_table)</p> <p>


3. class初始化


在查找主板时,提前对所有设备的class进行了初始化,调用关系如下,参考流程图③:


c</p> <p>select_machine -> find_default_machine -> object_class_foreach(type_table) -> object_class_foreach_tramp -> type_initialize(ti) -> ti->class_init -> mydevice_class_init</p> <p>


4. instance初始化


main_impl中执行设备初始化时,会遍历所有添加到命令参数-device中的设备,新设备在此将完成实例化创建。调用关系如下,参考流程图④:


c</p> <p>qemu_opts_foreach(device) -> device_init_func -> qdev_device_add -> object_new(my-device) -> object_new_with_type(ti) -> object_initialize_with_type(ti) -> ti->instance_init -> mydevice_instance_init</p> <p>


5. 设备实例化


当设备固有属性初始化完成后,将进行设备的创建操作,对应操作仍在qdev_device_add中,在object_new完成后执行。设备创建通过qdev的realize体系完成,在instance_init环节中qdev注册了realize属性,设备创建将通过realize属性置true**来实现。调用关系如下,参考流程图⑤:


c</p> <p>qdev_device_add -> object_property_set_bool(realize) -> device_set_realized -> dc->realize -> mydevice_realize</p> <p>


此处需要注意,先前在class_init中修改了父设备的realize执行函数,因此此处dc->realize将指向我们自己定义的函数

相关文章
|
2月前
|
开发框架 供应链 监控
并行开发模型详解:类型、步骤及其应用解析
在现代研发环境中,企业需要在有限时间内推出高质量的产品,以满足客户不断变化的需求。传统的线性开发模式往往拖慢进度,导致资源浪费和延迟交付。并行开发模型通过允许多个开发阶段同时进行,极大提高了产品开发的效率和响应能力。本文将深入解析并行开发模型,涵盖其类型、步骤及如何通过辅助工具优化团队协作和管理工作流。
75 3
|
2月前
|
机器学习/深度学习 数据采集 算法
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
这篇博客文章介绍了如何使用包含多个网络和多种训练策略的框架来完成多目标分类任务,涵盖了从数据准备到训练、测试和部署的完整流程,并提供了相关代码和配置文件。
68 0
目标分类笔记(一): 利用包含多个网络多种训练策略的框架来完成多目标分类任务(从数据准备到训练测试部署的完整流程)
|
2月前
|
机器学习/深度学习 并行计算 数据可视化
目标分类笔记(二): 利用PaddleClas的框架来完成多标签分类任务(从数据准备到训练测试部署的完整流程)
这篇文章介绍了如何使用PaddleClas框架完成多标签分类任务,包括数据准备、环境搭建、模型训练、预测、评估等完整流程。
166 0
|
2月前
|
机器学习/深度学习 人工智能 自然语言处理
大模型的特点、重要概念及工作方式详解
大模型是具有大量参数和复杂结构的深度学习模型,通过处理大量数据实现高效任务解决。其特点包括参数规模庞大、深层网络结构、预训练与微调、多任务学习和自适应能力。重要概念有注意力机制、Transformer架构、迁移学习和分布式训练。大模型的工作方式包括输入处理、特征提取、预测与损失计算、反向传播与优化,以及评估与微调。这些特性使其在自然语言处理、计算机视觉等领域取得显著进展。
284 0
|
6月前
|
监控 Kubernetes 测试技术
概括模型开发部署流程
**模型部署流程概览:**训练完成的大型语言模型经验证评估,进行剪枝量化后导出为标准格式。封装成API,部署到云服务器,考虑GPU资源与安全。通过Docker或Kubernetes管理,集成后端服务,确保负载均衡和安全。监控性能,执行A/B测试和灰度发布,持续优化与维护。每个步骤涉及团队协作与线上稳定性。
72 1
|
7月前
|
机器学习/深度学习 数据采集 人工智能
人工智能,应该如何测试?(四)模型全生命周期流程与测试图
本文补充了完整的业务和测试流程,包括生命周期流程图,强调测试人员在模型测试中的角色。主要测试活动有:1) 离线模型测试,使用训练集、验证集和测试集评估模型;2) 线上线下一致性测试,确保特征工程的一致性;3) A/B Test,逐步替换新旧模型以观察效果;4) 线上模型监控,实时跟踪用户行为变化;5) 数据质量测试,验证新数据质量以防影响模型效果。
|
数据采集 算法 数据可视化
MMdetection框架速成系列 第03部分:简述整体构建细节与模块+训练测试模块流程剖析+深入解析代码模块与核心实现
按照抽象到具体方式,从多个层次进行训练和测试流程深入解析,从最抽象层讲起,到最后核心代码实现,希望帮助大家更容易理解 MMDetection 开源框架整体构建细节
613 0
|
Linux
嵌入式驱动开发案例实例过程
嵌入式驱动开发案例实例过程
149 0
|
分布式计算 大数据 Spark
阶段练习_需求介绍和明确步骤 | 学习笔记
快速学习 阶段练习_需求介绍和明确步骤
112 0
阶段练习_需求介绍和明确步骤 | 学习笔记
|
图形学 计算机视觉
3D建模入门学习方法,制作过程的六个主要阶段讲解
从来没有接触过建模的小白们是否都很好奇 自己最喜欢的3D电影或者是游戏角色 比如说《哪吒之魔童降世》里面的哪吒 《王者荣耀》里面的人物等等 都是怎样制作出来的呢?
151 0
3D建模入门学习方法,制作过程的六个主要阶段讲解

热门文章

最新文章