diff --git a/src/emu/CMakeLists.txt b/src/emu/CMakeLists.txt index 5cdbdf8..4219ae3 100644 --- a/src/emu/CMakeLists.txt +++ b/src/emu/CMakeLists.txt @@ -42,10 +42,8 @@ add_library(emu STATIC track.c thread.c extend.c - ovni/probe.c - ovni/create.c ovni/event.c - ovni/finish.c + ovni/setup.c nanos6/setup.c nanos6/event.c nosv/setup.c diff --git a/src/emu/ovni/connect.c b/src/emu/ovni/connect.c deleted file mode 100644 index 6dce39e..0000000 --- a/src/emu/ovni/connect.c +++ /dev/null @@ -1,181 +0,0 @@ -#include "ovni_priv.h" - -static const int th_type[] = { - [CH_FLUSH] = 7, -}; - -static const int *cpu_type = th_type; - - -static int -connect_thread_mux(struct emu *emu, struct thread *thread) -{ - struct ovni_thread *th = EXT(thread, 'O'); - for (int i = 0; i < CH_MAX; i++) { - struct chan *inp = &th->ch[i]; - struct chan *sel = &thread->chan[TH_CHAN_STATE]; - struct mux *mux_run = &th->mux_run[i]; - mux_select_func_t selrun = thread_select_running; - if (mux_init(mux_run, &emu->bay, sel, &th->ch_run[i], selrun) != 0) { - err("mux_init failed"); - return -1; - } - - if (mux_add_input(mux_run, value_int64(0), inp) != 0) { - err("mux_add_input failed"); - return -1; - } - } - - return 0; -} - -static int -connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv) -{ - struct ovni_thread *th = EXT(thread, 'O'); - for (int i = 0; i < CH_MAX; i++) { - struct chan *out = th->ch_out[i]; - long type = th_type[i]; - long row = thread->gindex; - if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { - err("prv_register failed"); - return -1; - } - } - - return 0; -} - -static int -add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i) -{ - for (struct thread *t = emu->system.threads; t; t = t->gnext) { - struct ovni_thread *th = EXT(t, 'O'); - struct chan *inp = &th->ch_run[i]; - if (mux_add_input(mux, value_int64(t->gindex), inp) != 0) { - err("mux_add_input failed"); - return -1; - } - } - - return 0; -} - -static int -connect_cpu_mux(struct emu *emu, struct cpu *scpu) -{ - struct ovni_cpu *cpu = EXT(scpu, 'O'); - for (int i = 0; i < CH_MAX; i++) { - struct mux *mux = &cpu->mux[i]; - struct chan *out = &cpu->ch[i]; - struct chan *sel = &scpu->chan[CPU_CHAN_THRUN]; - - if (mux_init(mux, &emu->bay, sel, out, NULL) != 0) { - err("mux_init failed"); - return -1; - } - - if (add_inputs_cpu_mux(emu, mux, i) != 0) { - err("add_inputs_cpu_mux failed"); - return -1; - } - } - - return 0; -} - -static int -connect_threads(struct emu *emu) -{ - struct system *sys = &emu->system; - - /* threads */ - for (struct thread *t = sys->threads; t; t = t->gnext) { - if (connect_thread_mux(emu, t) != 0) { - err("connect_thread_mux failed"); - return -1; - } - } - - /* Get thread PRV */ - struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread"); - if (pvt == NULL) { - err("cannot find thread pvt"); - return -1; - } - struct prv *prv = pvt_get_prv(pvt); - - for (struct thread *t = sys->threads; t; t = t->gnext) { - if (connect_thread_prv(emu, t, prv) != 0) { - err("connect_thread_prv failed"); - return -1; - } - } - - return 0; -} - -static int -connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv) -{ - struct ovni_cpu *cpu = EXT(scpu, 'O'); - for (int i = 0; i < CH_MAX; i++) { - struct chan *out = &cpu->ch[i]; - long type = cpu_type[i]; - long row = scpu->gindex; - if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { - err("prv_register failed"); - return -1; - } - } - - return 0; -} - -static int -connect_cpus(struct emu *emu) -{ - struct system *sys = &emu->system; - - /* cpus */ - for (struct cpu *c = sys->cpus; c; c = c->next) { - if (connect_cpu_mux(emu, c) != 0) { - err("connect_cpu_mux failed"); - return -1; - } - } - - /* Get cpu PRV */ - struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu"); - if (pvt == NULL) { - err("cannot find cpu pvt"); - return -1; - } - struct prv *prv = pvt_get_prv(pvt); - - for (struct cpu *c = sys->cpus; c; c = c->next) { - if (connect_cpu_prv(emu, c, prv) != 0) { - err("connect_cpu_prv failed"); - return -1; - } - } - - return 0; -} - -int -ovni_connect(struct emu *emu) -{ - if (connect_threads(emu) != 0) { - err("connect_threads failed"); - return -1; - } - - if (connect_cpus(emu) != 0) { - err("connect_cpus failed"); - return -1; - } - - return 0; -} diff --git a/src/emu/ovni/create.c b/src/emu/ovni/create.c deleted file mode 100644 index bd0e6f8..0000000 --- a/src/emu/ovni/create.c +++ /dev/null @@ -1,90 +0,0 @@ -#include "ovni_priv.h" - -static const char chan_fmt_cpu[] = "ovni.cpu%ld.%s"; -static const char chan_fmt_th_raw[] = "ovni.thread%ld.%s.raw"; -static const char chan_fmt_th_run[] = "ovni.thread%ld.%s.run"; - -static const char *chan_name[] = { - [CH_FLUSH] = "flush", -}; - -static int -init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex) -{ - for (int i = 0; i < CH_MAX; i++) { - struct chan *c = &chans[i]; - chan_init(c, CHAN_SINGLE, fmt, gindex, chan_name[i]); - - if (bay_register(bay, c) != 0) { - err("bay_register failed"); - return -1; - } - } - - return 0; -} - -static int -init_cpu(struct bay *bay, struct cpu *syscpu) -{ - struct ovni_cpu *cpu = calloc(1, sizeof(struct ovni_cpu)); - if (cpu == NULL) { - err("calloc failed:"); - return -1; - } - - if (init_chans(bay, cpu->ch, chan_fmt_cpu, syscpu->gindex) != 0) { - err("init_chans failed"); - return -1; - } - - extend_set(&syscpu->ext, 'O', cpu); - return 0; -} - -static int -init_thread(struct bay *bay, struct thread *systh) -{ - struct ovni_thread *th = calloc(1, sizeof(struct ovni_thread)); - if (th == NULL) { - err("calloc failed:"); - return -1; - } - - if (init_chans(bay, th->ch, chan_fmt_th_raw, systh->gindex) != 0) { - err("init_chans failed"); - return -1; - } - - if (init_chans(bay, th->ch_run, chan_fmt_th_run, systh->gindex) != 0) { - err("init_chans failed"); - return -1; - } - - extend_set(&systh->ext, 'O', th); - - return 0; -} - -int -ovni_create(struct emu *emu) -{ - struct system *sys = &emu->system; - struct bay *bay = &emu->bay; - - for (struct cpu *c = sys->cpus; c; c = c->next) { - if (init_cpu(bay, c) != 0) { - err("init_cpu failed"); - return -1; - } - } - - for (struct thread *t = sys->threads; t; t = t->gnext) { - if (init_thread(bay, t) != 0) { - err("init_thread failed"); - return -1; - } - } - - return 0; -} diff --git a/src/emu/ovni/finish.c b/src/emu/ovni/finish.c deleted file mode 100644 index 578897e..0000000 --- a/src/emu/ovni/finish.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) - * SPDX-License-Identifier: GPL-3.0-or-later */ - -#include "ovni_priv.h" - -int -ovni_finish(struct emu *emu) -{ - /* Skip the check if the we are stopping prematurely */ - if (!emu->finished) - return 0; - - struct system *sys = &emu->system; - int ret = 0; - - /* Ensure that all threads are in the Dead state */ - for (struct thread *t = sys->threads; t; t = t->gnext) { - if (t->state != TH_ST_DEAD) { - err("thread %d is not dead (%s)", t->tid, t->id); - ret = -1; - } - } - - return ret; -} diff --git a/src/emu/ovni/ovni_priv.h b/src/emu/ovni/ovni_priv.h index cbc0148..20a92e2 100644 --- a/src/emu/ovni/ovni_priv.h +++ b/src/emu/ovni/ovni_priv.h @@ -10,7 +10,8 @@ * execution by the kernel. */ #include "emu.h" -#include "chan.h" +#include "model_cpu.h" +#include "model_thread.h" #include enum ovni_chan_type { @@ -18,25 +19,29 @@ enum ovni_chan_type { CH_MAX, }; +enum ovni_flusing_st { + ST_FLUSHING = 1, +}; + #define MAX_BURSTS 100 struct ovni_thread { - struct chan ch[CH_MAX]; - struct chan ch_run[CH_MAX]; - struct chan mux_run[CH_MAX]; + struct model_thread m; /* Burst times */ int nbursts; int64_t burst_time[MAX_BURSTS]; + + int64_t flush_start; }; struct ovni_cpu { - struct chan ch[CH_MAX]; - struct mux mux[CH_MAX]; + struct model_cpu m; }; int ovni_probe(struct emu *emu); int ovni_create(struct emu *emu); +int ovni_connect(struct emu *emu); int ovni_event(struct emu *emu); int ovni_finish(struct emu *emu); diff --git a/src/emu/ovni/probe.c b/src/emu/ovni/probe.c deleted file mode 100644 index dcd072a..0000000 --- a/src/emu/ovni/probe.c +++ /dev/null @@ -1,23 +0,0 @@ -/* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) - * SPDX-License-Identifier: GPL-3.0-or-later */ - -#include "ovni_priv.h" - -struct model_spec model_ovni = { - .name = "ovni", - .model = 'O', - .create = ovni_create, - .connect = NULL, - .event = ovni_event, - .probe = ovni_probe, - .finish = ovni_finish, -}; - -int -ovni_probe(struct emu *emu) -{ - if (emu->system.nthreads == 0) - return 1; - - return 0; -} diff --git a/src/emu/ovni/setup.c b/src/emu/ovni/setup.c new file mode 100644 index 0000000..bf78da4 --- /dev/null +++ b/src/emu/ovni/setup.c @@ -0,0 +1,155 @@ +#include "ovni_priv.h" + +static const char model_name[] = "ovni"; +enum { model_id = 'O' }; + +struct model_spec model_ovni = { + .name = model_name, + .model = model_id, + .create = ovni_create, + .connect = ovni_connect, + .event = ovni_event, + .probe = ovni_probe, + .finish = ovni_finish, +}; + +/* ----------------- channels ------------------ */ + +static const char *chan_name[CH_MAX] = { + [CH_FLUSH] = "flush", +}; + +static const int chan_stack[CH_MAX] = { 0 }; + +/* ----------------- pvt ------------------ */ + +static const int pvt_type[] = { + [CH_FLUSH] = 7, +}; + +static const char *pcf_prefix[CH_MAX] = { + [CH_FLUSH] = "Flushing ovni buffer", +}; + +static const struct pcf_value_label flushing_values[] = { + { ST_FLUSHING, "Flushing" }, + { -1, NULL }, +}; + +static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { + [CH_FLUSH] = &flushing_values, +}; + +static const struct model_pvt_spec pvt_spec = { + .type = pvt_type, + .prefix = pcf_prefix, + .label = pcf_labels, +}; + +/* ----------------- tracking ------------------ */ + +static const int th_track[CH_MAX] = { + [CH_FLUSH] = TRACK_TH_ANY, +}; + +static const int cpu_track[CH_MAX] = { + [CH_FLUSH] = TRACK_TH_RUN, +}; + +/* ----------------- chan_spec ------------------ */ + +static const struct model_chan_spec th_chan = { + .nch = CH_MAX, + .prefix = model_name, + .ch_names = chan_name, + .ch_stack = chan_stack, + .pvt = &pvt_spec, + .track = th_track, +}; + +static const struct model_chan_spec cpu_chan = { + .nch = CH_MAX, + .prefix = model_name, + .ch_names = chan_name, + .ch_stack = chan_stack, + .pvt = &pvt_spec, + .track = cpu_track, +}; + +/* ----------------- models ------------------ */ + +static const struct model_cpu_spec cpu_spec = { + .size = sizeof(struct ovni_cpu), + .chan = &cpu_chan, + .model = &model_ovni, +}; + +static const struct model_thread_spec th_spec = { + .size = sizeof(struct ovni_thread), + .chan = &th_chan, + .model = &model_ovni, +}; + +/* ----------------------------------------------------- */ + +int +ovni_probe(struct emu *emu) +{ + if (emu->system.nthreads == 0) + return 1; + + return 0; +} + +int +ovni_create(struct emu *emu) +{ + if (model_thread_create(emu, &th_spec) != 0) { + err("model_thread_init failed"); + return -1; + } + + if (model_cpu_create(emu, &cpu_spec) != 0) { + err("model_cpu_init failed"); + return -1; + } + + return 0; +} + +int +ovni_connect(struct emu *emu) +{ + if (model_thread_connect(emu, &th_spec) != 0) { + err("model_thread_connect failed"); + return -1; + } + + if (model_cpu_connect(emu, &cpu_spec) != 0) { + err("model_cpu_connect failed"); + return -1; + } + + return 0; +} + +int +ovni_finish(struct emu *emu) +{ + /* Skip the check if the we are stopping prematurely */ + if (!emu->finished) + return 0; + + struct system *sys = &emu->system; + int ret = 0; + + /* Ensure that all threads are in the Dead state */ + for (struct thread *t = sys->threads; t; t = t->gnext) { + if (t->state != TH_ST_DEAD) { + err("thread %d is not dead (%s)", t->tid, t->id); + ret = -1; + } + } + + return ret; +}