QEMU源码全解析39 —— Machine(9)

88 篇文章 19 订阅
本文深入解析QEMU源码中的Machine结构,通过引用《趣谈Linux操作系统》和《QEMU/KVM》相关资料,探讨了MACHINE函数的定义、OBJECT_CHECK宏的使用,以及object_dynamic_cast_assert函数的实现。文章介绍了Object作为所有对象祖先的定义,并阐述了Machine类型检查的重要性。下一部分将结合实际应用进一步展开分析。
摘要由CSDN通过智能技术生成

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

本文内容参考:

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

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

特此致谢!

上一回经过层层展开探索,终于看到了MACHINE的定义,实际上它是一个函数,代码如下(include/hw/boards.h中):

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

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

  1. /**
  2. * OBJECT_CHECK:
  3. * @type: The C type to use for the return value.
  4. * @obj: A derivative of @type to cast.
  5. * @name: The QOM typename of @type
  6. *
  7. * A type safe version of @object_dynamic_cast_assert. Typically each class
  8. * will define a macro based on this type to perform type safe dynamic_casts to
  9. * this object type.
  10. *
  11. * If an invalid object is passed to this function, a run time assert will be
  12. * generated.
  13. */
  14. #define OBJECT_CHECK(type, obj, name) \
  15. ((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \
  16. __FILE__, __LINE__, __func__))

因此,代入宏定义后,MACHINE函数的最终代码为:

  1. static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
  2. {
  3. return ((MachineState*)object_dynamic_cast_assert(OBJECT(obj), ("machine"), __FILE__, __LINE__, __func__));
  4. }

object_dynamic_cast_assert函数在qom/object.c中,代码如下:

  1. Object *object_dynamic_cast_assert(Object *obj, const char *typename,
  2. const char *file, int line, const char *func)
  3. {
  4. trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
  5. typename, file, line, func);
  6. #ifdef CONFIG_QOM_CAST_DEBUG
  7. int i;
  8. Object *inst;
  9. for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
  10. if (qatomic_read(&obj->class->object_cast_cache[i]) == typename) {
  11. goto out;
  12. }
  13. }
  14. inst = object_dynamic_cast(obj, typename);
  15. if (!inst && obj) {
  16. fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
  17. file, line, func, obj, typename);
  18. abort();
  19. }
  20. assert(obj == inst);
  21. if (obj && obj == inst) {
  22. for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
  23. qatomic_set(&obj->class->object_cast_cache[i - 1],
  24. qatomic_read(&obj->class->object_cast_cache[i]));
  25. }
  26. qatomic_set(&obj->class->object_cast_cache[i - 1], typename);
  27. }
  28. out:
  29. #endif
  30. return obj;
  31. }

Object前文已介绍过,是所有对象的祖先。这里为了便于理解,再给出其代码。在include/ qemu /typedefs.h中定义,如下:

typedef struct Object Object;

struct Object在中定义,代码如下:

  1. /**
  2. * struct Object:
  3. *
  4. * The base for all objects. The first member of this object is a pointer to
  5. * a #ObjectClass. Since C guarantees that the first member of a structure
  6. * always begins at byte 0 of that structure, as long as any sub-object places
  7. * its parent as the first member, we can cast directly to a #Object.
  8. *
  9. * As a result, #Object contains a reference to the objects type as its
  10. * first member. This allows identification of the real type of the object at
  11. * run time.
  12. */
  13. struct Object
  14. {
  15. /* private: */
  16. ObjectClass *class;
  17. ObjectFree *free;
  18. GHashTable *properties;
  19. uint32_t ref;
  20. Object *parent;
  21. };

实际上就是类型进行检查,确保传入的对象类型是machine类型。

本着“一张一弛”的原则,本回就到这里。下一回将结合实际调用MACHINE宏的地方,继续深入展开分析。

举报

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