Features/QOM

From QEMU

QEMU Object Model

This page describes the QEMU Object Model (QOM), a unified approach to expressing relationships among devices and between devices and backends.

Rationale

Much of the complexity of QEMU involves creating discrete objects (devices or backends), describing the relationships between these options, and providing easy ways to express complex relationships (machines). A large part of this complexity comes from the fact that all backends implement ad-hoc object models. Historically, devices have also used an ad-hoc object model although qdev attempted to standardize the device object model. qdev falls short of what's needed though to properly model devices.

QOM attempts to fix the short-comings of qdev and also generalize the object model enough such that it can be also used to model backends and their relationships with devices.

Concepts

All objects are described by a struct. Inheritance is expressed by setting the first member of the struct to the parent object. All new types have an optional class structure associated with them. Classes express inheritance by setting the first member of the struct to the parent class.

Only a single instance of a class will ever exist for a given type. Classes contain a reference to the type which is used by the type system. They also contain any virtual or pure virtual methods associated with the class.

Consider the following example:

#include "type.h"

typedef struct Person {
    TypeInstance parent;

    /* public */
    bool gender;
} Person;

typedef struct PersonClass {
    TypeClass parent_class;

    /* public */
    void (*jump)(Person *person, int distance);
} PersonClass;

#define TYPE_PERSON "person"
#define PERSON(obj) TYPE_CHECK(Person, obj, TYPE_PERSON)
#define PERSON_CLASS(class) TYPE_CLASS_CHECK(PersonClass, class, TYPE_PERSON)

In this example, we also introduce three macros that are useful in working with the type. The first macro, TYPE_PERSON is the string name of the type. This is used to identify the type in the type system. The second macro, PERSON(obj) will perform a dynamic cast of an arbitrary typed object to a Person object. It can perform both down casts and up casts across multiple levels. If the obj is not a valid Person instance, it currently asserts. PERSON_CLASS(class) is similar to PERSON(obj) but performs casts of the class type.