Use the model functions to simplify ovni model
This commit is contained in:
parent
02dbf0b993
commit
55c8af6b4d
@ -42,10 +42,8 @@ add_library(emu STATIC
|
|||||||
track.c
|
track.c
|
||||||
thread.c
|
thread.c
|
||||||
extend.c
|
extend.c
|
||||||
ovni/probe.c
|
|
||||||
ovni/create.c
|
|
||||||
ovni/event.c
|
ovni/event.c
|
||||||
ovni/finish.c
|
ovni/setup.c
|
||||||
nanos6/setup.c
|
nanos6/setup.c
|
||||||
nanos6/event.c
|
nanos6/event.c
|
||||||
nosv/setup.c
|
nosv/setup.c
|
||||||
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -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;
|
|
||||||
}
|
|
@ -10,7 +10,8 @@
|
|||||||
* execution by the kernel. */
|
* execution by the kernel. */
|
||||||
|
|
||||||
#include "emu.h"
|
#include "emu.h"
|
||||||
#include "chan.h"
|
#include "model_cpu.h"
|
||||||
|
#include "model_thread.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
enum ovni_chan_type {
|
enum ovni_chan_type {
|
||||||
@ -18,25 +19,29 @@ enum ovni_chan_type {
|
|||||||
CH_MAX,
|
CH_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum ovni_flusing_st {
|
||||||
|
ST_FLUSHING = 1,
|
||||||
|
};
|
||||||
|
|
||||||
#define MAX_BURSTS 100
|
#define MAX_BURSTS 100
|
||||||
|
|
||||||
struct ovni_thread {
|
struct ovni_thread {
|
||||||
struct chan ch[CH_MAX];
|
struct model_thread m;
|
||||||
struct chan ch_run[CH_MAX];
|
|
||||||
struct chan mux_run[CH_MAX];
|
|
||||||
|
|
||||||
/* Burst times */
|
/* Burst times */
|
||||||
int nbursts;
|
int nbursts;
|
||||||
int64_t burst_time[MAX_BURSTS];
|
int64_t burst_time[MAX_BURSTS];
|
||||||
|
|
||||||
|
int64_t flush_start;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ovni_cpu {
|
struct ovni_cpu {
|
||||||
struct chan ch[CH_MAX];
|
struct model_cpu m;
|
||||||
struct mux mux[CH_MAX];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
int ovni_probe(struct emu *emu);
|
int ovni_probe(struct emu *emu);
|
||||||
int ovni_create(struct emu *emu);
|
int ovni_create(struct emu *emu);
|
||||||
|
int ovni_connect(struct emu *emu);
|
||||||
int ovni_event(struct emu *emu);
|
int ovni_event(struct emu *emu);
|
||||||
int ovni_finish(struct emu *emu);
|
int ovni_finish(struct emu *emu);
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
}
|
|
155
src/emu/ovni/setup.c
Normal file
155
src/emu/ovni/setup.c
Normal file
@ -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;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user