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

88 篇文章 19 订阅
本文深入解析QEMU源码中的Machine定义,通过OBJECT_DECLARE_TYPE宏展开,逐步剖析DECLARE_OBJ_CHECKERS、DECLARE_INSTANCE_CHECKER和DECLARE_CLASS_CHECKERS等宏的细节,最终揭示Machine函数的真实面貌,为后续的源码分析打下基础。
摘要由CSDN通过智能技术生成

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

本文内容参考:

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

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

特此致谢!

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

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

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

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

  1. /**
  2. * OBJECT_DECLARE_TYPE:
  3. * @InstanceType: instance struct name
  4. * @ClassType: class struct name
  5. * @MODULE_OBJ_NAME: the object name in uppercase with underscore separators
  6. *
  7. * This macro is typically used in a header file, and will:
  8. *
  9. * - create the typedefs for the object and class structs
  10. * - register the type for use with g_autoptr
  11. * - provide three standard type cast functions
  12. *
  13. * The object struct and class struct need to be declared manually.
  14. */
  15. #define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
  16. typedef struct InstanceType InstanceType; \
  17. typedef struct ClassType ClassType; \
  18. \
  19. G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
  20. \
  21. DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
  22. MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

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

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

  1. /**
  2. * DECLARE_OBJ_CHECKERS:
  3. * @InstanceType: instance struct name
  4. * @ClassType: class struct name
  5. * @OBJ_NAME: the object name in uppercase with underscore separators
  6. * @TYPENAME: type name
  7. *
  8. * Direct usage of this macro should be avoided, and the complete
  9. * OBJECT_DECLARE_TYPE macro is recommended instead.
  10. *
  11. * This macro will provide the three standard type cast functions for a
  12. * QOM type.
  13. */
  14. #define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
  15. DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
  16. \
  17. DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

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

  1. /**
  2. * DECLARE_INSTANCE_CHECKER:
  3. * @InstanceType: instance struct name
  4. * @OBJ_NAME: the object name in uppercase with underscore separators
  5. * @TYPENAME: type name
  6. *
  7. * Direct usage of this macro should be avoided, and the complete
  8. * OBJECT_DECLARE_TYPE macro is recommended instead.
  9. *
  10. * This macro will provide the instance type cast functions for a
  11. * QOM type.
  12. */
  13. #define DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
  14. static inline G_GNUC_UNUSED InstanceType * \
  15. OBJ_NAME(const void *obj) \
  16. { return OBJECT_CHECK(InstanceType, obj, TYPENAME); }
  1. /**
  2. * DECLARE_CLASS_CHECKERS:
  3. * @ClassType: class struct name
  4. * @OBJ_NAME: the object name in uppercase with underscore separators
  5. * @TYPENAME: type name
  6. *
  7. * Direct usage of this macro should be avoided, and the complete
  8. * OBJECT_DECLARE_TYPE macro is recommended instead.
  9. *
  10. * This macro will provide the class type cast functions for a
  11. * QOM type.
  12. */
  13. #define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
  14. static inline G_GNUC_UNUSED ClassType * \
  15. OBJ_NAME##_GET_CLASS(const void *obj) \
  16. { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
  17. \
  18. static inline G_GNUC_UNUSED ClassType * \
  19. OBJ_NAME##_CLASS(const void *klass) \
  20. { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

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

第1层:

  1. #define OBJECT_DECLARE_TYPE(InstanceType, ClassType, MODULE_OBJ_NAME) \
  2. typedef struct InstanceType InstanceType; \
  3. typedef struct ClassType ClassType; \
  4. \
  5. G_DEFINE_AUTOPTR_CLEANUP_FUNC(InstanceType, object_unref) \
  6. \
  7. DECLARE_OBJ_CHECKERS(InstanceType, ClassType, \
  8. MODULE_OBJ_NAME, TYPE_##MODULE_OBJ_NAME)

代入

OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)

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

  1. typedef struct MachineState MachineState;
  2. typedef struct MachineClass MachineClass;
  3. G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
  4. DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
  5. MACHINE, TYPE_MACHINE)

第2层:

  1. #define DECLARE_OBJ_CHECKERS(InstanceType, ClassType, OBJ_NAME, TYPENAME) \
  2. DECLARE_INSTANCE_CHECKER(InstanceType, OBJ_NAME, TYPENAME) \
  3. \
  4. DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME)

代入

  1. DECLARE_OBJ_CHECKERS(MachineState, MachineClass, \
  2. MACHINE, TYPE_MACHINE)

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

  1. DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE)
  2. DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

第3层:

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

  1. #define DECLARE_CLASS_CHECKERS(ClassType, OBJ_NAME, TYPENAME) \
  2. static inline G_GNUC_UNUSED ClassType * \
  3. OBJ_NAME##_GET_CLASS(const void *obj) \
  4. { return OBJECT_GET_CLASS(ClassType, obj, TYPENAME); } \
  5. \
  6. static inline G_GNUC_UNUSED ClassType * \
  7. OBJ_NAME##_CLASS(const void *klass) \
  8. { return OBJECT_CLASS_CHECK(ClassType, klass, TYPENAME); }

分别代入

  1. DECLARE_INSTANCE_CHECKER(MachineState, MACHINE, TYPE_MACHINE)
  2. DECLARE_CLASS_CHECKERS(MachineClass, MACHINE, TYPE_MACHINE)

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

  1. static inline G_GNUC_UNUSED MachineState *
  2. MACHINE(const void *obj)
  3. { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
  1. static inline G_GNUC_UNUSED MachineClass *
  2. MACHINE_GET_CLASS(const void *obj)
  3. { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); }
  4. static inline G_GNUC_UNUSED MachineClass *
  5. MACHINE_CLASS(const void *klass)
  6. { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

与上面综合,得到:

  1. typedef struct MachineState MachineState;
  2. typedef struct MachineClass MachineClass;
  3. G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
  4. static inline G_GNUC_UNUSED MachineState *
  5. MACHINE(const void *obj)
  6. { return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE); }
  7. static inline G_GNUC_UNUSED MachineClass *
  8. MACHINE_GET_CLASS(const void *obj)
  9. { return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE); }
  10. static inline G_GNUC_UNUSED MachineClass *
  11. MACHINE_CLASS(const void *klass)
  12. { return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE); }

整理成更好理解的格式:

  1. typedef struct MachineState MachineState;
  2. typedef struct MachineClass MachineClass;
  3. G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
  4. static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
  5. {
  6. return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
  7. }
  8. static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
  9. {
  10. return OBJECT_GET_CLASS(MachineClass, obj, TYPE_MACHINE);
  11. }
  12. static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
  13. {
  14. return OBJECT_CLASS_CHECK(MachineClass, klass, TYPE_MACHINE);
  15. }

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

#define TYPE_MACHINE "machine"

得到:

  1. typedef struct MachineState MachineState;
  2. typedef struct MachineClass MachineClass;
  3. G_DEFINE_AUTOPTR_CLEANUP_FUNC(MachineState, object_unref)
  4. static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
  5. {
  6. return OBJECT_CHECK(MachineState, obj, "machine");
  7. }
  8. static inline G_GNUC_UNUSED MachineClass *MACHINE_GET_CLASS(const void *obj)
  9. {
  10. return OBJECT_GET_CLASS(MachineClass, obj, "machine");
  11. }
  12. static inline G_GNUC_UNUSED MachineClass *MACHINE_CLASS(const void *klass)
  13. {
  14. return OBJECT_CLASS_CHECK(MachineClass, klass, "machine");
  15. }

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

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

  1. static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
  2. {
  3. return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
  4. }

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

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他