@@ -129,9 +129,12 @@ static void qbus_init_internal(BusState *bus, DeviceState *parent,
bus->parent->num_child_bus++;
object_property_add_child(OBJECT(bus->parent), bus->name, OBJECT(bus));
object_unref(OBJECT(bus));
+
+ /* The only bus without a parent is the main system bus */
+ assert(sysbus_get_default());
} else {
/* The only bus without a parent is the main system bus */
- assert(bus == sysbus_get_default());
+ assert(!sysbus_get_default());
}
}
@@ -1097,6 +1097,9 @@ static void machine_initfn(Object *obj)
ms->smp.threads = 1;
machine_copy_boot_config(ms, &(BootConfiguration){ 0 });
+
+ qbus_init(&ms->main_system_bus, sizeof(ms->main_system_bus),
+ TYPE_SYSTEM_BUS, NULL, "main-system-bus");
}
static void machine_finalize(Object *obj)
@@ -20,6 +20,7 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu/module.h"
+#include "hw/boards.h"
#include "hw/sysbus.h"
#include "monitor/monitor.h"
#include "exec/address-spaces.h"
@@ -336,26 +337,13 @@ static const TypeInfo sysbus_device_type_info = {
.class_init = sysbus_device_class_init,
};
-static BusState *main_system_bus;
-
-static void main_system_bus_create(void)
-{
- /*
- * assign main_system_bus before qbus_init()
- * in order to make "if (bus != sysbus_get_default())" work
- */
- main_system_bus = g_malloc0(system_bus_info.instance_size);
- qbus_init(main_system_bus, system_bus_info.instance_size,
- TYPE_SYSTEM_BUS, NULL, "main-system-bus");
- OBJECT(main_system_bus)->free = g_free;
-}
-
BusState *sysbus_get_default(void)
{
- if (!main_system_bus) {
- main_system_bus_create();
+ if (!current_machine) {
+ return NULL;
}
- return main_system_bus;
+
+ return ¤t_machine->main_system_bus;
}
static void sysbus_register_types(void)
@@ -346,6 +346,7 @@ struct MachineState {
*/
MemoryRegion *ram;
DeviceMemoryState *device_memory;
+ BusState main_system_bus;
ram_addr_t ram_size;
ram_addr_t maxram_size;
In QEMU, a machine and the main_system_bus always go togehter. Usually the bus is part of the machine which suggsts to host it there. Since tere is already a current_machine singleton, all code that accesses the main_system_bus can be changed (behind the scenes) to go through current_machine. This resolves a singleton. Futhermore, by reifying it in code, the every-machine-has-exactly-one-main-system-bus relationship becomes very obvious. Note that the main_system_bus attribute is a value rather than a pointer. This trades pointer dereferences for pointer arithmetic. The idea is to reduce cache misses - a rule of thumb says that every pointer dereference causes a cache miss while arithmetic is basically free. Signed-off-by: Bernhard Beschow <shentey@gmail.com> --- hw/core/bus.c | 5 ++++- hw/core/machine.c | 3 +++ hw/core/sysbus.c | 22 +++++----------------- include/hw/boards.h | 1 + 4 files changed, 13 insertions(+), 18 deletions(-)