From 9041583207c66dd7df5bc0779d085c4b834119b0 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Wed, 1 Feb 2023 13:07:10 +0100 Subject: [PATCH] Add support for multiple models --- src/emu/CMakeLists.txt | 3 +- src/emu/emu.c | 37 +++++++--------- src/emu/emu.h | 4 +- src/emu/emu_model.c | 27 ------------ src/emu/emu_model.h | 29 ------------- src/emu/model.c | 98 ++++++++++++++++++++++++++++++++++++++++++ src/emu/model.h | 34 +++++++++++++++ src/emu/models.c | 23 ++++++++++ src/emu/models.h | 6 +-- 9 files changed, 177 insertions(+), 84 deletions(-) delete mode 100644 src/emu/emu_model.c delete mode 100644 src/emu/emu_model.h create mode 100644 src/emu/model.c create mode 100644 src/emu/model.h create mode 100644 src/emu/models.c diff --git a/src/emu/CMakeLists.txt b/src/emu/CMakeLists.txt index 4088504..dce8776 100644 --- a/src/emu/CMakeLists.txt +++ b/src/emu/CMakeLists.txt @@ -17,7 +17,8 @@ add_library(emu STATIC emu.c emu_args.c emu_ev.c - emu_model.c + model.c + models.c player.c stream.c trace.c diff --git a/src/emu/emu.c b/src/emu/emu.c index b6d7a3f..5fbc6f5 100644 --- a/src/emu/emu.c +++ b/src/emu/emu.c @@ -51,18 +51,20 @@ emu_init(struct emu *emu, int argc, char *argv[]) return -1; } -// /* Register all the models */ -// emu_model_register(&emu->model, &ovni_model_spec, emu); + model_init(&emu->model); - if (model_ovni.create && model_ovni.create(emu) != 0) { - err("model ovni create failed"); - return -1; - } - if (model_nanos6.create && model_nanos6.create(emu) != 0) { - err("model nanos6 create failed"); + /* Register all the models */ + models_register(&emu->model); + + if (model_probe(&emu->model, emu) != 0) { + err("model_probe failed"); return -1; } + if (model_create(&emu->model, emu) != 0) { + err("model_create failed"); + return -1; + } return 0; } @@ -70,14 +72,11 @@ emu_init(struct emu *emu, int argc, char *argv[]) int emu_connect(struct emu *emu) { - if (model_ovni.connect && model_ovni.connect(emu) != 0) { - err("model ovni connect failed"); - return -1; - } - if (model_nanos6.connect && model_nanos6.connect(emu) != 0) { - err("model nanos6 connect failed"); + if (model_connect(&emu->model, emu) != 0) { + err("model_connect failed"); return -1; } + return 0; } @@ -143,14 +142,8 @@ emu_step(struct emu *emu) } /* Otherwise progress */ - if (emu->ev->m == 'O' && model_ovni.event(emu) != 0) { - err("ovni event failed"); - panic(emu); - return -1; - } - - if (emu->ev->m == '6' && model_nanos6.event(emu) != 0) { - err("nanos6 event failed"); + if (model_event(&emu->model, emu, emu->ev->m) != 0) { + err("model_event failed"); panic(emu); return -1; } diff --git a/src/emu/emu.h b/src/emu/emu.h index 8e184c6..5eade0b 100644 --- a/src/emu/emu.h +++ b/src/emu/emu.h @@ -9,7 +9,7 @@ #include "emu_args.h" #include "system.h" #include "player.h" -#include "emu_model.h" +#include "model.h" #include "emu_ev.h" #include "recorder.h" @@ -25,7 +25,7 @@ struct emu { struct trace trace; struct system system; struct player player; - struct emu_model model; + struct model model; struct recorder recorder; /* Quick access */ diff --git a/src/emu/emu_model.c b/src/emu/emu_model.c deleted file mode 100644 index 1345c99..0000000 --- a/src/emu/emu_model.c +++ /dev/null @@ -1,27 +0,0 @@ -/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) - * SPDX-License-Identifier: GPL-3.0-or-later */ - -#include "emu_model.h" - -#include - -int -emu_model_register(struct emu_model *model, struct model_spec *spec, void *ctx) -{ - int i = spec->model; - model->ctx[i] = ctx; - model->spec[i] = spec; - return 0; -} - -void * -emu_model_get_context(struct emu_model *model, struct model_spec *spec, int imodel) -{ - for (int i = 0; spec->depends[i]; i++) { - if (spec->depends[i] == imodel) - return model->ctx[imodel]; - } - - /* Not allowed */ - return NULL; -} diff --git a/src/emu/emu_model.h b/src/emu/emu_model.h deleted file mode 100644 index 00684e4..0000000 --- a/src/emu/emu_model.h +++ /dev/null @@ -1,29 +0,0 @@ -/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) - * SPDX-License-Identifier: GPL-3.0-or-later */ - -#ifndef EMU_MODEL_H -#define EMU_MODEL_H - -#include "emu_hook.h" - -struct model_spec { - char *name; - int model; - char *depends; - emu_hook_t *probe; - emu_hook_t *create; - emu_hook_t *connect; - emu_hook_t *event; -}; - -struct emu_model { - struct model_spec *spec[256]; - void *ctx[256]; -}; - -int emu_model_parse(struct emu_model *model, struct model_spec *spec, void *ctx); -int emu_model_register(struct emu_model *model, struct model_spec *spec, void *ctx); -int emu_model_register(struct emu_model *model, struct model_spec *spec, void *ctx); -void *emu_model_get_context(struct emu_model *model, struct model_spec *spec, int imodel); - -#endif /* EMU_MODEL_H */ diff --git a/src/emu/model.c b/src/emu/model.c new file mode 100644 index 0000000..abe86db --- /dev/null +++ b/src/emu/model.c @@ -0,0 +1,98 @@ +/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#include "model.h" + +#include "common.h" +#include + +void +model_init(struct model *model) +{ + memset(model, 0, sizeof(struct model)); +} + +void +model_register(struct model *model, struct model_spec *spec) +{ + int i = spec->model; + model->spec[i] = spec; + model->registered[i] = 1; +} + +int +model_probe(struct model *model, struct emu *emu) +{ + for (int i = 0; i < MAX_MODELS; i++) { + if (!model->registered[i]) + continue; + + struct model_spec *spec = model->spec[i]; + if (spec->probe == NULL) + continue; + + if (spec->probe(emu) != 0) { + err("probe failed for model '%c'", (char) i); + return -1; + } + } + return 0; +} + +int +model_create(struct model *model, struct emu *emu) +{ + for (int i = 0; i < MAX_MODELS; i++) { + if (!model->registered[i]) + continue; + + struct model_spec *spec = model->spec[i]; + if (spec->create == NULL) + continue; + + if (spec->create(emu) != 0) { + err("create failed for model '%c'", (char) i); + return -1; + } + } + return 0; +} + +int +model_connect(struct model *model, struct emu *emu) +{ + for (int i = 0; i < MAX_MODELS; i++) { + if (!model->registered[i]) + continue; + + struct model_spec *spec = model->spec[i]; + if (spec->connect == NULL) + continue; + + if (spec->connect(emu) != 0) { + err("connect failed for model '%c'", (char) i); + return -1; + } + } + return 0; +} + +int +model_event(struct model *model, struct emu *emu, int index) +{ + if (!model->registered[index]) { + err("no model registered for '%c'", (char) index); + return -1; + } + + struct model_spec *spec = model->spec[index]; + if (spec->event == NULL) + return 0; + + if (spec->event(emu) != 0) { + err("event() failed for model '%c'", (char) index); + return -1; + } + + return 0; +} diff --git a/src/emu/model.h b/src/emu/model.h new file mode 100644 index 0000000..c5d109e --- /dev/null +++ b/src/emu/model.h @@ -0,0 +1,34 @@ +/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef MODEL_H +#define MODEL_H + +#include "emu_hook.h" + +struct model_spec { + char *name; + int model; + char *depends; + emu_hook_t *probe; + emu_hook_t *create; + emu_hook_t *connect; + emu_hook_t *event; +}; + +#define MAX_MODELS 256 + +struct model { + struct model_spec *spec[MAX_MODELS]; + int registered[MAX_MODELS]; +}; + +void model_init(struct model *model); +void model_register(struct model *model, struct model_spec *spec); + +int model_probe(struct model *model, struct emu *emu); +int model_create(struct model *model, struct emu *emu); +int model_connect(struct model *model, struct emu *emu); +int model_event(struct model *model, struct emu *emu, int index); + +#endif /* MODEL_H */ diff --git a/src/emu/models.c b/src/emu/models.c new file mode 100644 index 0000000..d828b00 --- /dev/null +++ b/src/emu/models.c @@ -0,0 +1,23 @@ +/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#include "models.h" + +#include + +extern struct model_spec model_ovni; +extern struct model_spec model_nanos6; + +static struct model_spec *models[] = { + &model_ovni, + &model_nanos6, + NULL +}; + +void +models_register(struct model *model) +{ + for (int i = 0; models[i] != NULL; i++) { + model_register(model, models[i]); + } +} diff --git a/src/emu/models.h b/src/emu/models.h index 8d7bf2b..cca0e0c 100644 --- a/src/emu/models.h +++ b/src/emu/models.h @@ -4,9 +4,9 @@ #ifndef MODELS_H #define MODELS_H -#include "emu_model.h" +#include "model.h" -extern struct model_spec model_ovni; -extern struct model_spec model_nanos6; +void +models_register(struct model *model); #endif /* MODELS_H */