QEMU源码全解析38 —— Machine(8)

接前一篇文章:QEMU源码全解析37 —— Machine(7)

本文内容参考:

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

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

特此致谢!

上一回经过了重重周折,终于找到了MACHINE的定义所在:

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

本回就详细解析一下这段代码。别看代码只有一行,内容还是蛮多的。

OBJECT_DECLARE_TYPE是一个宏,在include/qom/object.h中定义,代码如下:

/**
 * OBJECT_DECLARE_TYPE:
 * @InstanceType: instance struct name
 * @ClassType: class struct name
 * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
 *
 * This macro is typically used in a header file, and will:
 *
 *   - create the typedefs for the object and class structs
 *   - register the type for use with g_autoptr
 *   - provide three standard type cast functions
 *
 * The object struct and class struct need to be declared manually.
 */
#define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
    typedef struct InstanceType InstanceType; \
    typedef struct ClassType ClassType; \
    \
    G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
    \
    DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
                         MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

这里边又涉及到两个宏:G_DEFINE_AUTOPTR_CLEANUP_FUNC和DECLARE_OBJ_CHECKERS。重点关注后一个。

DECLARE_OBJ_CHECKERS宏实际上就在OBJECT_DECLARE_TYPE宏的上边,代码如下:

/**
 * DECLARE_OBJ_CHECKERS:
 * @InstanceType: instance struct name
 * @ClassType: class struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the three standard type cast functions for a
 * QOM type.
 */
#define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
    DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    \
    DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

这里边又包含了DECLARE_INSTANCE_CHECKER和DECLARE_CLASS_CHECKERS两个宏定义。打破砂锅问到底,看看这两个宏的代码,实际上就在DECLARE_OBJ_CHECKERS宏的上边。

/**
 * DECLARE_INSTANCE_CHECKER:
 * @InstanceType: instance struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the instance type cast functions for a
 * QOM type.
 */
#define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED InstanceType * \
    OBJ_NAME(const void *obj) \
    { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
/**
 * DECLARE_CLASS_CHECKERS:
 * @ClassType: class struct name
 * @OBJ_NAME: the object name in uppercase with underscore separators
 * @TYPENAME: type name
 *
 * Direct usage of this macro should be avoided, and the complete
 * OBJECT_DECLARE_TYPE macro is recommended instead.
 *
 * This macro will provide the class type cast functions for a
 * QOM type.
 */
#define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_GET_CLASS(const void *obj) \
    { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
    \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_CLASS(const void *klass) \
    { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

好了,现在各个宏定义基本都已经给出了(G_DEFINE_AUTOPTR_CLEANUP_FUNC暂时不展开),开始逐层展开,到底看看完全展开之后是个内容。

第1层:

#define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
    typedef struct InstanceType InstanceType; \
    typedef struct ClassType ClassType; \
    \
    G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
    \
    DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
                         MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

代入

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,MODULE_OBJ_NAME <-> MACHINE,得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
                         MACHINE, TYPE_MACHINE)

第2层:

#define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
    DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    \
    DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

代入

DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
                         MACHINE, TYPE_MACHINE)

中的实际值:InstanceType <-> MachineState,ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE,得到:

    DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE) 

    DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

第3层:

#define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED InstanceType * \
    OBJ_NAME(const void *obj) \
    { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }

#define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_GET_CLASS(const void *obj) \
    { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
    \
    static inline G_GNUC_UNUSED ClassType * \
    OBJ_NAME##_CLASS(const void *klass) \
    { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

分别代入

    DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE) 

    DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

中的实际值:InstanceType <-> MachineState,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE;ClassType <-> MachineClass,OBJ_NAME <-> MACHINE,TYPENAME <-> TYPE_MACHINE分别得到:

    static inline G_GNUC_UNUSED MachineState * 
    MACHINE(const void *obj)
    { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_GET_CLASS(const void *obj) 
    { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); } 

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_CLASS(const void *klass) 
    { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

与上面综合,得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState * 
    MACHINE(const void *obj)
    { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_GET_CLASS(const void *obj) 
    { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); } 

    static inline G_GNUC_UNUSED MachineClass * 
    MACHINE_CLASS(const void *klass) 
    { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

整理成更好理解的格式:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
    {
        return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
    {
        return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE);
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
    {
        return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE);
    }

这就得到了初步形式。再将TYPE_MACHINE宏的定义(在include/hw/boards.h中)代入:

#define TYPE_MACHINE "machine"

得到:

    typedef struct MachineState MachineState;
    typedef struct MachineClass MachineClass;

    G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)

    static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
    {
        return OBJECT_CHECK(MachineState, obj, "machine");
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
    {
        return OBJECT_GET_CLASS(MachineClass, obj, "machine");
    }

    static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
    {
        return OBJECT_CLASS_CHECK(MachineClass, klass, "machine");
    }

对比一下在VSCode中展开的截图:

 终于看到了MACHINE函数的庐山真面目!原来是这样:

static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
{
    return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
}

下一回将对MACHINE函数及其相关函数进行进一步解析。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/132305521