From a818795d88d0ab84424e66cfdfedf738bb410021 Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Tue, 7 Feb 2023 13:34:18 +0100 Subject: [PATCH] Add support for nOS-V Most of the model is taken from nanos6, we should refactor them. --- src/emu/CMakeLists.txt | 6 + src/emu/cpu.c | 10 +- src/emu/cpu.h | 2 +- src/emu/emu.c | 2 +- src/emu/loom.c | 2 +- src/emu/metadata.c | 2 +- src/emu/model.c | 12 +- src/emu/models.c | 2 + src/emu/nanos6/connect.c | 10 +- src/emu/nanos6/create.c | 4 +- src/emu/nanos6/event.c | 2 - src/emu/nanos6/finish.c | 4 +- src/emu/nanos6/nanos6_priv.h | 8 +- src/emu/nanos6/pvt.c | 8 +- src/emu/nosv/connect.c | 150 +++++++++++ src/emu/nosv/create.c | 179 +++++++++++++ src/emu/nosv/event.c | 501 +++++++++++++++++++++++++++++++++++ src/emu/nosv/finish.c | 44 +++ src/emu/nosv/nosv_priv.h | 88 ++++++ src/emu/nosv/probe.c | 20 ++ src/emu/nosv/pvt.c | 273 +++++++++++++++++++ src/emu/ovni/event.c | 21 +- src/emu/pv/pcf.c | 26 -- test/emu/CMakeLists.txt | 2 +- test/emu/nosv/CMakeLists.txt | 2 +- test/rt/CMakeLists.txt | 2 +- test/rt/nosv/CMakeLists.txt | 6 +- test/unit/loom.c | 4 +- 28 files changed, 1331 insertions(+), 61 deletions(-) create mode 100644 src/emu/nosv/connect.c create mode 100644 src/emu/nosv/create.c create mode 100644 src/emu/nosv/event.c create mode 100644 src/emu/nosv/finish.c create mode 100644 src/emu/nosv/nosv_priv.h create mode 100644 src/emu/nosv/probe.c create mode 100644 src/emu/nosv/pvt.c diff --git a/src/emu/CMakeLists.txt b/src/emu/CMakeLists.txt index 3bd09ac..5f15815 100644 --- a/src/emu/CMakeLists.txt +++ b/src/emu/CMakeLists.txt @@ -45,6 +45,12 @@ add_library(emu STATIC nanos6/event.c nanos6/pvt.c nanos6/finish.c + nosv/probe.c + nosv/connect.c + nosv/create.c + nosv/event.c + nosv/pvt.c + nosv/finish.c ) add_executable(ovniemu ovniemu.c) diff --git a/src/emu/cpu.c b/src/emu/cpu.c index aace2f6..57eec3c 100644 --- a/src/emu/cpu.c +++ b/src/emu/cpu.c @@ -30,11 +30,12 @@ static int chan_type[] = { }; void -cpu_init_begin(struct cpu *cpu, int phyid) +cpu_init_begin(struct cpu *cpu, int phyid, int is_virtual) { memset(cpu, 0, sizeof(struct cpu)); cpu->phyid = phyid; + cpu->is_virtual = is_virtual; dbg("cpu init %d", phyid); } @@ -166,6 +167,13 @@ cpu_update(struct cpu *cpu) cpu->nth_running = running; cpu->nth_active = active; + /* Only virtual cpus can be oversubscribed */ + if (cpu->nth_running > 1 && !cpu->is_virtual) { + err("physical cpu %s has %d thread running at the same time", + cpu->name, cpu->nth_running); + return -1; + } + struct value tid_running; struct value pid_running; struct value gid_running; diff --git a/src/emu/cpu.h b/src/emu/cpu.h index 9853ba0..81b0e75 100644 --- a/src/emu/cpu.h +++ b/src/emu/cpu.h @@ -61,7 +61,7 @@ struct cpu { UT_hash_handle hh; /* CPUs in the loom */ }; -void cpu_init_begin(struct cpu *cpu, int phyid); +void cpu_init_begin(struct cpu *cpu, int phyid, int is_virtual); int cpu_get_phyid(struct cpu *cpu); //int cpu_get_index(struct cpu *cpu); void cpu_set_gindex(struct cpu *cpu, int64_t gindex); diff --git a/src/emu/emu.c b/src/emu/emu.c index 881febf..cf3528b 100644 --- a/src/emu/emu.c +++ b/src/emu/emu.c @@ -3,7 +3,7 @@ #define _POSIX_C_SOURCE 2 -//#define ENABLE_DEBUG +#define ENABLE_DEBUG #include "emu.h" diff --git a/src/emu/loom.c b/src/emu/loom.c index 3f2cd0d..b1f54ef 100644 --- a/src/emu/loom.c +++ b/src/emu/loom.c @@ -64,7 +64,7 @@ loom_init_begin(struct loom *loom, const char *name) set_hostname(loom->hostname, loom->name); loom->id = loom->name; - cpu_init_begin(&loom->vcpu, -1); + cpu_init_begin(&loom->vcpu, -1, 1); dbg("creating new loom %s", loom->id); diff --git a/src/emu/metadata.c b/src/emu/metadata.c index 5a90089..98a6e27 100644 --- a/src/emu/metadata.c +++ b/src/emu/metadata.c @@ -105,7 +105,7 @@ load_cpus(struct loom *loom, JSON_Object *meta) return -1; } - cpu_init_begin(cpu, phyid); + cpu_init_begin(cpu, phyid, 0); if (loom_add_cpu(loom, cpu) != 0) { err("loom_add_cpu() failed"); diff --git a/src/emu/model.c b/src/emu/model.c index 4bda566..625234d 100644 --- a/src/emu/model.c +++ b/src/emu/model.c @@ -1,6 +1,8 @@ /* Copyright (c) 2021-2023 Barcelona Supercomputing Center (BSC) * SPDX-License-Identifier: GPL-3.0-or-later */ +#define ENABLE_DEBUG + #include "model.h" #include "common.h" @@ -18,6 +20,8 @@ model_register(struct model *model, struct model_spec *spec) int i = spec->model; model->spec[i] = spec; model->registered[i] = 1; + + dbg("registered model %c", (char) i); } int @@ -37,8 +41,12 @@ model_probe(struct model *model, struct emu *emu) return -1; } - if (ret == 0) + if (ret == 0) { model->enabled[i] = 1; + dbg("model %c enabled", (char) i); + } else { + dbg("model %c disabled", (char) i); + } } return 0; } @@ -77,6 +85,8 @@ model_connect(struct model *model, struct emu *emu) err("connect failed for model '%c'", (char) i); return -1; } + + dbg("connect for model %c ok", (char) i); } return 0; } diff --git a/src/emu/models.c b/src/emu/models.c index d828b00..026be46 100644 --- a/src/emu/models.c +++ b/src/emu/models.c @@ -7,10 +7,12 @@ extern struct model_spec model_ovni; extern struct model_spec model_nanos6; +extern struct model_spec model_nosv; static struct model_spec *models[] = { &model_ovni, &model_nanos6, + &model_nosv, NULL }; diff --git a/src/emu/nanos6/connect.c b/src/emu/nanos6/connect.c index 4c81495..91d12ec 100644 --- a/src/emu/nanos6/connect.c +++ b/src/emu/nanos6/connect.c @@ -1,6 +1,6 @@ #include "nanos6_priv.h" -const enum nanos6_track chan_track[CH_MAX][CT_MAX] = { +const enum nanos6_track nanos6_chan_track[CH_MAX][CT_MAX] = { /* Thread CPU */ [CH_TASKID] = { RUN_TH, RUN_TH }, [CH_TYPE] = { RUN_TH, RUN_TH }, @@ -49,7 +49,7 @@ connect_thread_mux(struct emu *emu, struct thread *thread) /* The tracking only sets the ch_out, but we keep both tracking * updated as the CPU tracking channels may use them. */ - enum nanos6_track track = chan_track[i][CT_TH]; + enum nanos6_track track = nanos6_chan_track[i][CT_TH]; if (track == RUN_TH) th->ch_out[i] = &th->ch_run[i]; else if (track == ACT_TH) @@ -70,7 +70,7 @@ add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i) /* Choose input thread channel based on tracking mode */ struct chan *inp = NULL; - enum nanos6_track track = chan_track[i][CT_CPU]; + enum nanos6_track track = nanos6_chan_track[i][CT_CPU]; if (track == RUN_TH) inp = &th->ch_run[i]; else if (track == ACT_TH) @@ -97,7 +97,7 @@ connect_cpu_mux(struct emu *emu, struct cpu *scpu) /* Choose select CPU channel based on tracking mode */ struct chan *sel = NULL; - enum nanos6_track track = chan_track[i][CT_CPU]; + enum nanos6_track track = nanos6_chan_track[i][CT_CPU]; if (track == RUN_TH) sel = &scpu->chan[CPU_CHAN_THRUN]; else if (track == ACT_TH) @@ -140,7 +140,7 @@ nanos6_connect(struct emu *emu) } } - if (init_pvt(emu) != 0) { + if (nanos6_init_pvt(emu) != 0) { err("init_pvt failed"); return -1; } diff --git a/src/emu/nanos6/create.c b/src/emu/nanos6/create.c index da28581..f1a29a0 100644 --- a/src/emu/nanos6/create.c +++ b/src/emu/nanos6/create.c @@ -7,7 +7,7 @@ static const char chan_fmt_th_raw[] = "nanos6.thread%ld.%s.raw"; static const char chan_fmt_th_run[] = "nanos6.thread%ld.%s.run"; static const char chan_fmt_th_act[] = "nanos6.thread%ld.%s.act"; -static const char *chan_name[] = { +static const char *chan_name[CH_MAX] = { [CH_TASKID] = "taskid", [CH_TYPE] = "task_type", [CH_SUBSYSTEM] = "subsystem", @@ -15,7 +15,7 @@ static const char *chan_name[] = { [CH_THREAD] = "thread_type", }; -static const int chan_stack[] = { +static const int chan_stack[CH_MAX] = { [CH_SUBSYSTEM] = 1, [CH_THREAD] = 1, }; diff --git a/src/emu/nanos6/event.c b/src/emu/nanos6/event.c index 3e7870f..0cc9e20 100644 --- a/src/emu/nanos6/event.c +++ b/src/emu/nanos6/event.c @@ -520,7 +520,5 @@ nanos6_event(struct emu *emu) return -1; } - //check_affinity(emu); - return 0; } diff --git a/src/emu/nanos6/finish.c b/src/emu/nanos6/finish.c index ce240df..e860414 100644 --- a/src/emu/nanos6/finish.c +++ b/src/emu/nanos6/finish.c @@ -18,7 +18,7 @@ end_lint(struct emu *emu) } err("thread %d ended with %d stacked nanos6 subsystems, top=\"%s\"\n", - t->tid, stacked, ss_name(top.i)); + t->tid, stacked, nanos6_ss_name(top.i)); return -1; } } @@ -29,7 +29,7 @@ end_lint(struct emu *emu) int nanos6_finish(struct emu *emu) { - if (finish_pvt(emu) != 0) { + if (nanos6_finish_pvt(emu) != 0) { err("finish_pvt failed"); return -1; } diff --git a/src/emu/nanos6/nanos6_priv.h b/src/emu/nanos6/nanos6_priv.h index 7a410b0..9f7989e 100644 --- a/src/emu/nanos6/nanos6_priv.h +++ b/src/emu/nanos6/nanos6_priv.h @@ -33,7 +33,7 @@ enum nanos6_track { TRACK_MAX, }; -extern const enum nanos6_track chan_track[CH_MAX][CT_MAX]; +extern const enum nanos6_track nanos6_chan_track[CH_MAX][CT_MAX]; enum nanos6_ss_state { ST_TASK_BODY = 1, @@ -100,8 +100,8 @@ int nanos6_connect(struct emu *emu); int nanos6_event(struct emu *emu); int nanos6_finish(struct emu *emu); -int init_pvt(struct emu *emu); -int finish_pvt(struct emu *emu); -const char *ss_name(int ss); +int nanos6_init_pvt(struct emu *emu); +int nanos6_finish_pvt(struct emu *emu); +const char *nanos6_ss_name(int ss); #endif /* NANOS6_PRIV_H */ diff --git a/src/emu/nanos6/pvt.c b/src/emu/nanos6/pvt.c index 8f7b429..4b3db9c 100644 --- a/src/emu/nanos6/pvt.c +++ b/src/emu/nanos6/pvt.c @@ -101,7 +101,7 @@ create_type(struct pcf *pcf, enum nanos6_chan c, enum nanos6_chan_type ct) /* Compute the label by joining the two parts */ const char *prefix = pcf_prefix[c]; - int track_mode = chan_track[c][ct]; + int track_mode = nanos6_chan_track[c][ct]; const char *suffix = pcf_suffix[track_mode]; char label[MAX_PCF_LABEL]; @@ -232,7 +232,7 @@ connect_cpus(struct emu *emu) /* Connect all outputs to the paraver trace and setup PCF types */ int -init_pvt(struct emu *emu) +nanos6_init_pvt(struct emu *emu) { if (connect_threads(emu) != 0) { err("connect_threads failed"); @@ -248,7 +248,7 @@ init_pvt(struct emu *emu) } int -finish_pvt(struct emu *emu) +nanos6_finish_pvt(struct emu *emu) { struct system *sys = &emu->system; @@ -277,7 +277,7 @@ finish_pvt(struct emu *emu) } const char * -ss_name(int ss) +nanos6_ss_name(int ss) { static const char *unknown = "(unknown)"; const char *name = unknown; diff --git a/src/emu/nosv/connect.c b/src/emu/nosv/connect.c new file mode 100644 index 0000000..7529ca2 --- /dev/null +++ b/src/emu/nosv/connect.c @@ -0,0 +1,150 @@ +#include "nosv_priv.h" + +const enum nosv_track nosv_chan_track[CH_MAX][CT_MAX] = { + /* Thread CPU */ + [CH_TASKID] = { RUN_TH, RUN_TH }, + [CH_TYPE] = { RUN_TH, RUN_TH }, + [CH_APPID] = { RUN_TH, RUN_TH }, + [CH_SUBSYSTEM] = { ACT_TH, RUN_TH }, + [CH_RANK] = { RUN_TH, RUN_TH }, +}; + + +static int +connect_thread_mux(struct emu *emu, struct thread *thread) +{ + struct nosv_thread *th = EXT(thread, 'V'); + for (int i = 0; i < CH_MAX; i++) { + + /* TODO: Let the thread take the select channel + * and build the mux as a tracking mode */ + 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; + } + + struct mux *mux_act = &th->mux_act[i]; + mux_select_func_t selact = thread_select_active; + if (mux_init(mux_act, &emu->bay, sel, &th->ch_act[i], selact) != 0) { + err("mux_init failed"); + return -1; + } + + if (mux_add_input(mux_act, value_int64(0), inp) != 0) { + err("mux_add_input failed"); + return -1; + } + + if (mux_act->ninputs != 1) + die("expecting one input only"); + + /* The tracking only sets the ch_out, but we keep both tracking + * updated as the CPU tracking channels may use them. */ + enum nosv_track track = nosv_chan_track[i][CT_TH]; + if (track == RUN_TH) + th->ch_out[i] = &th->ch_run[i]; + else if (track == ACT_TH) + th->ch_out[i] = &th->ch_act[i]; + else + th->ch_out[i] = &th->ch[i]; + + } + + 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 nosv_thread *th = EXT(t, 'V'); + + /* Choose input thread channel based on tracking mode */ + struct chan *inp = NULL; + enum nosv_track track = nosv_chan_track[i][CT_CPU]; + if (track == RUN_TH) + inp = &th->ch_run[i]; + else if (track == ACT_TH) + inp = &th->ch_act[i]; + else + die("cpu tracking must be running or active"); + + 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 nosv_cpu *cpu = EXT(scpu, 'V'); + for (int i = 0; i < CH_MAX; i++) { + struct mux *mux = &cpu->mux[i]; + struct chan *out = &cpu->ch[i]; + + /* Choose select CPU channel based on tracking mode */ + struct chan *sel = NULL; + enum nosv_track track = nosv_chan_track[i][CT_CPU]; + if (track == RUN_TH) + sel = &scpu->chan[CPU_CHAN_THRUN]; + else if (track == ACT_TH) + sel = &scpu->chan[CPU_CHAN_THACT]; + else + die("cpu tracking must be running or active"); + + 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; +} + +int +nosv_connect(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; + } + } + + /* 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; + } + } + + if (nosv_init_pvt(emu) != 0) { + err("init_pvt failed"); + return -1; + } + + return 0; +} diff --git a/src/emu/nosv/create.c b/src/emu/nosv/create.c new file mode 100644 index 0000000..03c5c31 --- /dev/null +++ b/src/emu/nosv/create.c @@ -0,0 +1,179 @@ +#include "nosv_priv.h" + +static const char chan_fmt_cpu_raw[] = "nosv.cpu%ld.%s"; +//static const char chan_fmt_cpu_run[] = "nosv.cpu%ld.%s.run"; +//static const char chan_fmt_cpu_act[] = "nosv.cpu%ld.%s.act"; +static const char chan_fmt_th_raw[] = "nosv.thread%ld.%s.raw"; +static const char chan_fmt_th_run[] = "nosv.thread%ld.%s.run"; +static const char chan_fmt_th_act[] = "nosv.thread%ld.%s.act"; + +static const char *chan_name[CH_MAX] = { + [CH_TASKID] = "taskid", + [CH_TYPE] = "task_type", + [CH_APPID] = "appid", + [CH_SUBSYSTEM] = "subsystem", + [CH_RANK] = "rank", +}; + +static const int chan_stack[CH_MAX] = { + [CH_SUBSYSTEM] = 1, +}; + +static int +init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex, int filtered) +{ + for (int i = 0; i < CH_MAX; i++) { + struct chan *c = &chans[i]; + int type = (chan_stack[i] && !filtered) ? CHAN_STACK : CHAN_SINGLE; + chan_init(c, type, 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 nosv_cpu *cpu = calloc(1, sizeof(struct nosv_cpu)); + if (cpu == NULL) { + err("calloc failed:"); + return -1; + } + + cpu->ch = calloc(CH_MAX, sizeof(struct chan)); + if (cpu->ch == NULL) { + err("calloc failed:"); + return -1; + } + + cpu->mux = calloc(CH_MAX, sizeof(struct mux)); + if (cpu->mux == NULL) { + err("calloc failed:"); + return -1; + } + + if (init_chans(bay, cpu->ch, chan_fmt_cpu_raw, syscpu->gindex, 1) != 0) { + err("init_chans failed"); + return -1; + } + + extend_set(&syscpu->ext, 'V', cpu); + return 0; +} + +static int +init_thread(struct bay *bay, struct thread *systh) +{ + struct nosv_thread *th = calloc(1, sizeof(struct nosv_thread)); + if (th == NULL) { + err("calloc failed:"); + return -1; + } + + th->ch = calloc(CH_MAX, sizeof(struct chan)); + if (th->ch == NULL) { + err("calloc failed:"); + return -1; + } + + th->ch_run = calloc(CH_MAX, sizeof(struct chan)); + if (th->ch_run == NULL) { + err("calloc failed:"); + return -1; + } + + th->ch_act = calloc(CH_MAX, sizeof(struct chan)); + if (th->ch_act == NULL) { + err("calloc failed:"); + return -1; + } + + th->ch_out = calloc(CH_MAX, sizeof(struct chan *)); + if (th->ch_out == NULL) { + err("calloc failed:"); + return -1; + } + + th->mux_run = calloc(CH_MAX, sizeof(struct mux)); + if (th->mux_run == NULL) { + err("calloc failed:"); + return -1; + } + + th->mux_act = calloc(CH_MAX, sizeof(struct mux)); + if (th->mux_act == NULL) { + err("calloc failed:"); + return -1; + } + + if (init_chans(bay, th->ch, chan_fmt_th_raw, systh->gindex, 0) != 0) { + err("init_chans failed"); + return -1; + } + + if (init_chans(bay, th->ch_run, chan_fmt_th_run, systh->gindex, 1) != 0) { + err("init_chans failed"); + return -1; + } + + if (init_chans(bay, th->ch_act, chan_fmt_th_act, systh->gindex, 1) != 0) { + err("init_chans failed"); + return -1; + } + + + th->task_stack.thread = systh; + + extend_set(&systh->ext, 'V', th); + + return 0; +} + +static int +init_proc(struct proc *sysproc) +{ + struct nosv_proc *proc = calloc(1, sizeof(struct nosv_proc)); + if (proc == NULL) { + err("calloc failed:"); + return -1; + } + + extend_set(&sysproc->ext, 'V', proc); + + return 0; +} + +int +nosv_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; + } + } + + for (struct proc *p = sys->procs; p; p = p->gnext) { + if (init_proc(p) != 0) { + err("init_proc failed"); + return -1; + } + } + + return 0; +} diff --git a/src/emu/nosv/event.c b/src/emu/nosv/event.c new file mode 100644 index 0000000..4b24e84 --- /dev/null +++ b/src/emu/nosv/event.c @@ -0,0 +1,501 @@ +#include "nosv_priv.h" + +enum { PUSH = 1, POP = 2, IGN = 3 }; + +#define CHSS CH_SUBSYSTEM + +static const int ss_table[256][256][3] = { + ['S'] = { + ['h'] = { CHSS, PUSH, ST_SCHED_HUNGRY }, + ['f'] = { CHSS, POP, ST_SCHED_HUNGRY }, + ['['] = { CHSS, PUSH, ST_SCHED_SERVING }, + [']'] = { CHSS, POP, ST_SCHED_SERVING }, + ['@'] = { CHSS, IGN, -1 }, + ['r'] = { CHSS, IGN, -1 }, + ['s'] = { CHSS, IGN, -1 }, + }, + ['U'] = { + ['['] = { CHSS, PUSH, ST_SCHED_SUBMITTING }, + [']'] = { CHSS, POP, ST_SCHED_SUBMITTING }, + }, + ['M'] = { + ['a'] = { CHSS, PUSH, ST_MEM_ALLOCATING }, + ['A'] = { CHSS, POP, ST_MEM_ALLOCATING }, + ['f'] = { CHSS, PUSH, ST_MEM_FREEING }, + ['F'] = { CHSS, POP, ST_MEM_FREEING }, + }, + ['A'] = { + ['s'] = { CHSS, PUSH, ST_API_SUBMIT }, + ['S'] = { CHSS, POP, ST_API_SUBMIT }, + ['p'] = { CHSS, PUSH, ST_API_PAUSE }, + ['P'] = { CHSS, POP, ST_API_PAUSE }, + ['y'] = { CHSS, PUSH, ST_API_YIELD }, + ['Y'] = { CHSS, POP, ST_API_YIELD }, + ['w'] = { CHSS, PUSH, ST_API_WAITFOR }, + ['W'] = { CHSS, POP, ST_API_WAITFOR }, + ['c'] = { CHSS, PUSH, ST_API_SCHEDPOINT }, + ['C'] = { CHSS, POP, ST_API_SCHEDPOINT }, + }, + /* FIXME: Move thread type to another channel, like nanos6 */ + ['H'] = { + ['a'] = { CHSS, PUSH, ST_ATTACH }, + ['A'] = { CHSS, POP, ST_ATTACH }, + ['w'] = { CHSS, PUSH, ST_WORKER }, + ['W'] = { CHSS, POP, ST_WORKER }, + ['d'] = { CHSS, PUSH, ST_DELEGATE }, + ['D'] = { CHSS, POP, ST_DELEGATE }, + }, +}; + +static int +simple(struct emu *emu) +{ + const int *entry = ss_table[emu->ev->c][emu->ev->v]; + int chind = entry[0]; + int action = entry[1]; + int st = entry[2]; + + struct nosv_thread *th = EXT(emu->thread, 'V'); + struct chan *ch = &th->ch[chind]; + + if (action == PUSH) { + return chan_push(ch, value_int64(st)); + } else if (action == POP) { + return chan_pop(ch, value_int64(st)); + } else if (action == IGN) { + return 0; /* do nothing */ + } else { + err("unknown nOS-V subsystem event"); + return -1; + } + + return 0; +} + +static int +chan_task_stopped(struct emu *emu) +{ + struct nosv_thread *th = EXT(emu->thread, 'V'); + + struct value null = value_null(); + if (chan_set(&th->ch[CH_TASKID], null) != 0) { + err("chan_set taskid failed"); + return -1; + } + if (chan_set(&th->ch[CH_TYPE], null) != 0) { + err("chan_set type failed"); + return -1; + } + if (chan_set(&th->ch[CH_APPID], null) != 0) { + err("chan_set appid failed"); + return -1; + } + + struct proc *proc = emu->proc; + if (proc->rank >= 0) { + if (chan_set(&th->ch[CH_RANK], null) != 0) { + err("chan_set rank failed"); + return -1; + } + } + + /* FIXME: Do we need this transition? */ + if (chan_pop(&th->ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) { + err("chan_pop subsystem failed"); + return -1; + } + + return 0; +} + +static int +chan_task_running(struct emu *emu, struct task *task) +{ + struct nosv_thread *th = EXT(emu->thread, 'V'); + struct proc *proc = emu->proc; + struct chan *ch = th->ch; + + if (task->id == 0) { + err("task id cannot be 0"); + return -1; + } + if (task->type->gid == 0) { + err("task type gid cannot be 0"); + return -1; + } + if (proc->appid <= 0) { + err("app id must be positive"); + return -1; + } + + if (chan_set(&ch[CH_TASKID], value_int64(task->id)) != 0) { + err("chan_set taskid failed"); + return -1; + } + if (chan_set(&ch[CH_TYPE], value_int64(task->type->gid)) != 0) { + err("chan_set type failed"); + return -1; + } + if (chan_set(&ch[CH_APPID], value_int64(proc->appid)) != 0) { + err("chan_set appid failed"); + return -1; + } + if (proc->rank >= 0) { + struct value vrank = value_int64(proc->rank + 1); + if (chan_set(&ch[CH_RANK], vrank) != 0) { + err("chan_set rank failed"); + return -1; + } + } + if (chan_push(&ch[CH_SUBSYSTEM], value_int64(ST_TASK_RUNNING)) != 0) { + err("chan_push subsystem failed"); + return -1; + } + + return 0; +} + +static int +chan_task_switch(struct emu *emu, + struct task *prev, struct task *next) +{ + struct nosv_thread *th = EXT(emu->thread, 'V'); + + if (!prev || !next) { + err("cannot switch to or from a NULL task"); + return -1; + } + + if (prev == next) { + err("cannot switch to the same task"); + return -1; + } + + if (next->id == 0) { + err("next task id cannot be 0"); + return -1; + } + + if (next->type->gid == 0) { + err("next task type id cannot be 0"); + return -1; + } + + if (prev->thread != next->thread) { + err("cannot switch to a task of another thread"); + return -1; + } + + /* No need to change the rank or app ID as we will switch + * to tasks from same thread */ + if (chan_set(&th->ch[CH_TASKID], value_int64(next->id)) != 0) { + err("chan_set taskid failed"); + return -1; + } + + /* TODO: test when switching to another task with the same type. We + * should emit the same type state value as previous task. */ + if (chan_set(&th->ch[CH_TYPE], value_int64(next->type->gid)) != 0) { + err("chan_set type failed"); + return -1; + } + + return 0; +} + +static int +update_task_state(struct emu *emu) +{ + if (emu->ev->payload_size < 4) { + err("missing task id in payload"); + return -1; + } + + uint32_t task_id = emu->ev->payload->u32[0]; + + struct nosv_thread *th = EXT(emu->thread, 'V'); + struct nosv_proc *proc = EXT(emu->proc, 'V'); + + struct task_info *info = &proc->task_info; + struct task_stack *stack = &th->task_stack; + + struct task *task = task_find(info->tasks, task_id); + + if (task == NULL) { + err("cannot find task with id %u", task_id); + return -1; + } + + int ret = 0; + switch (emu->ev->v) { + case 'x': + ret = task_execute(stack, task); + break; + case 'e': + ret = task_end(stack, task); + break; + case 'p': + ret = task_pause(stack, task); + break; + case 'r': + ret = task_resume(stack, task); + break; + default: + err("unexpected nOS-V task event"); + return -1; + } + + if (ret != 0) { + err("cannot change task state"); + return -1; + } + + return 0; +} + +static int +expand_transition_value(struct emu *emu, int was_running, int runs_now, char *tr_p) +{ + char tr = emu->ev->v; + + /* Ensure we don't clobber the value */ + if (tr == 'X' || tr == 'E') { + err("unexpected event value %c", tr); + return -1; + } + + /* Modify the event value to detect nested transitions */ + if (tr == 'x' && was_running) + tr = 'X'; /* Execute a new nested task */ + else if (tr == 'e' && runs_now) + tr = 'E'; /* End a nested task */ + + *tr_p = tr; + return 0; +} + +static int +update_task_channels(struct emu *emu, + char tr, struct task *prev, struct task *next) +{ + int ret = 0; + switch (tr) { + case 'x': + case 'r': + ret = chan_task_running(emu, next); + break; + case 'e': + case 'p': + ret = chan_task_stopped(emu); + break; + /* Additional nested transitions */ + case 'X': + case 'E': + ret = chan_task_switch(emu, prev, next); + break; + default: + err("unexpected transition value %c", tr); + return -1; + } + + if (ret != 0) { + err("cannot update task channels"); + return -1; + } + + return 0; +} + +static int +enforce_task_rules(struct emu *emu, char tr, struct task *next) +{ + if (tr != 'x' && tr != 'X') + return 0; + + /* If a task has just entered the running state, it must show + * the running task body subsystem */ + + if (next->state != TASK_ST_RUNNING) { + err("task not in running state on begin"); + return -1; + } + + struct nosv_thread *th = EXT(emu->thread, 'V'); + struct value ss; + if (chan_read(&th->ch[CH_SUBSYSTEM], &ss) != 0) { + err("chan_read failed"); + return -1; + } + + if (ss.type == VALUE_INT64 && ss.i != ST_TASK_RUNNING) { + err("wrong subsystem state on task begin"); + //return -1; + return 0; // FIXME + } + + return 0; +} + +static int +update_task(struct emu *emu) +{ + struct nosv_thread *th = EXT(emu->thread, 'V'); + struct task_stack *stack = &th->task_stack; + + struct task *prev = task_get_running(stack); + + /* Update the emulator state, but don't modify the channels */ + if (update_task_state(emu) != 0) { + err("update_task_state failed"); + return -1; + } + + struct task *next = task_get_running(stack); + + int was_running = (prev != NULL); + int runs_now = (next != NULL); + char tr; + if (expand_transition_value(emu, was_running, runs_now, &tr) != 0) { + err("expand_transition_value failed"); + return -1; + } + + /* Update the task related channels now */ + update_task_channels(emu, tr, prev, next); + + if (enforce_task_rules(emu, tr, next) != 0) { + err("enforce_task_rules failed"); + return -1; + } + + return 0; +} + +static int +create_task(struct emu *emu) +{ + if (emu->ev->payload_size != 8) { + err("unexpected payload size"); + return -1; + } + + uint32_t task_id = emu->ev->payload->u32[0]; + uint32_t type_id = emu->ev->payload->u32[1]; + + struct nosv_proc *proc = EXT(emu->proc, 'V'); + struct task_info *info = &proc->task_info; + + if (task_create(info, type_id, task_id) != 0) { + err("task_create failed"); + return -1; + } + + dbg("task created with taskid %u", task_id); + + return 0; +} + +static int +pre_task(struct emu *emu) +{ + int ret = 0; + switch (emu->ev->v) { + case 'c': + ret = create_task(emu); + break; + case 'x': + case 'e': + case 'r': + case 'p': + ret = update_task(emu); + break; + default: + err("unexpected nOS-V task event value"); + return -1; + } + + if (ret != 0) { + err("cannot update task state"); + return -1; + } + + return 0; +} + +static int +pre_type(struct emu *emu) +{ + uint8_t value = emu->ev->v; + + if (value != 'c') { + err("unexpected event value %c", value); + return -1; + } + + if (!emu->ev->is_jumbo) { + err("expecting a jumbo event"); + return -1; + } + + const uint8_t *data = &emu->ev->payload->jumbo.data[0]; + uint32_t typeid = *(uint32_t *) data; + data += 4; + + const char *label = (const char *) data; + + struct nosv_proc *proc = EXT(emu->proc, 'V'); + struct task_info *info = &proc->task_info; + + if (task_type_create(info, typeid, label) != 0) { + err("task_type_create failed"); + return -1; + } + + return 0; +} + +static int +process_ev(struct emu *emu) +{ + if (!emu->thread->is_active) { + err("current thread %d not active", emu->thread->tid); + return -1; + } + + switch (emu->ev->c) { + case 'S': + case 'U': + case 'M': + case 'H': + case 'A': + return simple(emu); + case 'T': + return pre_task(emu); + case 'Y': + return pre_type(emu); + default: + err("unknown nOS-V event category"); + return -1; + } + + /* Not reached */ + return 0; +} + +int +nosv_event(struct emu *emu) +{ + dbg("in nosv_event"); + if (emu->ev->m != 'V') { + err("unexpected event model %c\n", emu->ev->m); + return -1; + } + + dbg("got nosv event %s", emu->ev->mcv); + if (process_ev(emu) != 0) { + err("error processing nOS-V event"); + return -1; + } + + return 0; +} diff --git a/src/emu/nosv/finish.c b/src/emu/nosv/finish.c new file mode 100644 index 0000000..b60ac9b --- /dev/null +++ b/src/emu/nosv/finish.c @@ -0,0 +1,44 @@ +#include "nosv_priv.h" + +static int +end_lint(struct emu *emu) +{ + struct system *sys = &emu->system; + + /* Ensure we run out of subsystem states */ + for (struct thread *t = sys->threads; t; t = t->gnext) { + struct nosv_thread *th = EXT(t, 'V'); + struct chan *ch = &th->ch[CH_SUBSYSTEM]; + int stacked = ch->data.stack.n; + if (stacked > 0) { + struct value top; + if (chan_read(ch, &top) != 0) { + err("chan_read failed for subsystem"); + return -1; + } + + err("thread %d ended with %d stacked nosv subsystems, top=\"%s\"\n", + t->tid, stacked, nosv_ss_name(top.i)); + return -1; + } + } + + return 0; +} + +int +nosv_finish(struct emu *emu) +{ + if (nosv_finish_pvt(emu) != 0) { + err("finish_pvt failed"); + return -1; + } + + /* When running in linter mode perform additional checks */ + if (emu->args.linter_mode && end_lint(emu) != 0) { + err("end_lint failed"); + return -1; + } + + return 0; +} diff --git a/src/emu/nosv/nosv_priv.h b/src/emu/nosv/nosv_priv.h new file mode 100644 index 0000000..9a28c05 --- /dev/null +++ b/src/emu/nosv/nosv_priv.h @@ -0,0 +1,88 @@ +/* Copyright (c) 2023 Barcelona Supercomputing Center (BSC) + * SPDX-License-Identifier: GPL-3.0-or-later */ + +#ifndef NOSV_PRIV_H +#define NOSV_PRIV_H + +#include "emu.h" +#include "chan.h" +#include "mux.h" +#include "task.h" + +/* Private enums */ + +enum nosv_chan_type { + CT_TH = 0, + CT_CPU, + CT_MAX +}; + +enum nosv_chan { + CH_TASKID = 0, + CH_TYPE, + CH_APPID, + CH_SUBSYSTEM, + CH_RANK, + CH_MAX, +}; + +enum nosv_track { + NONE = 0, + RUN_TH, + ACT_TH, + TRACK_MAX, +}; + +extern const enum nosv_track nosv_chan_track[CH_MAX][CT_MAX]; + +enum nosv_ss_values { + ST_SCHED_HUNGRY = 6, + ST_SCHED_SERVING, + ST_SCHED_SUBMITTING, + ST_MEM_ALLOCATING, + ST_MEM_FREEING, + ST_TASK_RUNNING, + ST_API_SUBMIT, + ST_API_PAUSE, + ST_API_YIELD, + ST_API_WAITFOR, + ST_API_SCHEDPOINT, + ST_ATTACH, + ST_WORKER, + ST_DELEGATE, + + EV_SCHED_RECV, + EV_SCHED_SEND, + EV_SCHED_SELF, +}; + +struct nosv_thread { + struct chan *ch; /* Raw, modified by nosv */ + struct chan *ch_run; /* Tracking running thread */ + struct chan *ch_act; /* Tracking active thread */ + struct chan **ch_out; /* Output to PRV */ + struct mux *mux_run; + struct mux *mux_act; + struct task_stack task_stack; +}; + +struct nosv_cpu { + struct chan *ch; + struct mux *mux; +}; + +struct nosv_proc { + struct task_info task_info; +}; + +int nosv_probe(struct emu *emu); +int nosv_create(struct emu *emu); +int nosv_connect(struct emu *emu); +int nosv_event(struct emu *emu); +int nosv_finish(struct emu *emu); + +int nosv_init_pvt(struct emu *emu); +int nosv_finish_pvt(struct emu *emu); +const char *nosv_ss_name(int ss); + +#endif /* NOSV_PRIV_H */ diff --git a/src/emu/nosv/probe.c b/src/emu/nosv/probe.c new file mode 100644 index 0000000..93fc071 --- /dev/null +++ b/src/emu/nosv/probe.c @@ -0,0 +1,20 @@ +#include "nosv_priv.h" + +struct model_spec model_nosv = { + .name = "nosv", + .model = 'V', + .create = nosv_create, + .connect = nosv_connect, + .event = nosv_event, + .probe = nosv_probe, + .finish = nosv_finish, +}; + +int +nosv_probe(struct emu *emu) +{ + if (emu->system.nthreads == 0) + return 1; + + return 0; +} diff --git a/src/emu/nosv/pvt.c b/src/emu/nosv/pvt.c new file mode 100644 index 0000000..9a5b0c5 --- /dev/null +++ b/src/emu/nosv/pvt.c @@ -0,0 +1,273 @@ +#include "nosv_priv.h" + +/* TODO: Assign types on runtime and generate configs */ + +static const char *pvt_name[CT_MAX] = { + [CT_TH] = "thread", + [CT_CPU] = "cpu", +}; + +static const int pvt_type[] = { + [CH_TASKID] = 10, + [CH_TYPE] = 11, + [CH_APPID] = 12, + [CH_SUBSYSTEM] = 13, + [CH_RANK] = 14, +}; + +static const char *pcf_prefix[CH_MAX] = { + [CH_TASKID] = "nOS-V task ID", + [CH_TYPE] = "nOS-V task type", + [CH_APPID] = "nOS-V task AppID", + [CH_SUBSYSTEM] = "nOS-V subsystem", + [CH_RANK] = "nOS-V task MPI rank", +}; + + +static const char *pcf_suffix[TRACK_MAX] = { + [NONE] = "", + [RUN_TH] = "of the RUNNING thread", + [ACT_TH] = "of the ACTIVE thread", +}; + +static const struct pcf_value_label nosv_ss_values[] = { + { ST_SCHED_HUNGRY, "Scheduler: Hungry" }, + { ST_SCHED_SERVING, "Scheduler: Serving" }, + { ST_SCHED_SUBMITTING, "Scheduler: Submitting" }, + { ST_MEM_ALLOCATING, "Memory: Allocating" }, + { ST_MEM_FREEING, "Memory: Freeing" }, + { ST_TASK_RUNNING, "Task: Running" }, + { ST_API_SUBMIT, "API: Submit" }, + { ST_API_PAUSE, "API: Pause" }, + { ST_API_YIELD, "API: Yield" }, + { ST_API_WAITFOR, "API: Waitfor" }, + { ST_API_SCHEDPOINT, "API: Scheduling point" }, + { ST_ATTACH, "Thread: Attached" }, + { ST_WORKER, "Thread: Worker" }, + { ST_DELEGATE, "Thread: Delegate" }, + { EV_SCHED_SEND, "EV Scheduler: Send task" }, + { EV_SCHED_RECV, "EV Scheduler: Recv task" }, + { EV_SCHED_SELF, "EV Scheduler: Self-assign task" }, + { -1, NULL }, +}; + +static const struct pcf_value_label (*pcf_chan_value_labels[CH_MAX])[] = { + [CH_SUBSYSTEM] = &nosv_ss_values, +}; + +/* ------------------------------ pcf ------------------------------ */ + +static int +create_values(struct pcf_type *t, int c) +{ + const struct pcf_value_label(*q)[] = pcf_chan_value_labels[c]; + + if (q == NULL) + return 0; + + for (const struct pcf_value_label *p = *q; p->label != NULL; p++) + pcf_add_value(t, p->value, p->label); + + return 0; +} + +static int +create_type(struct pcf *pcf, enum nosv_chan c, enum nosv_chan_type ct) +{ + long type = pvt_type[c]; + + if (type == -1) + return 0; + + /* Compute the label by joining the two parts */ + const char *prefix = pcf_prefix[c]; + int track_mode = nosv_chan_track[c][ct]; + const char *suffix = pcf_suffix[track_mode]; + + char label[MAX_PCF_LABEL]; + int ret = snprintf(label, MAX_PCF_LABEL, "%s %s", + prefix, suffix); + + if (ret >= MAX_PCF_LABEL) { + err("computed type label too long"); + return -1; + } + + struct pcf_type *pcftype = pcf_add_type(pcf, type, label); + + return create_values(pcftype, c); +} + +static int +init_pcf(struct pcf *pcf, enum nosv_chan_type ct) +{ + /* Create default types and values */ + for (enum nosv_chan c = 0; c < CH_MAX; c++) { + if (create_type(pcf, c, ct) != 0) { + err("create_type failed"); + return -1; + } + } + + return 0; +} + +/* ------------------------------ prv ------------------------------ */ + +static int +connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv) +{ + struct nosv_thread *th = EXT(thread, 'V'); + for (int i = 0; i < CH_MAX; i++) { + struct chan *out = th->ch_out[i]; + long type = pvt_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 +connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv) +{ + struct nosv_cpu *cpu = EXT(scpu, 'V'); + for (int i = 0; i < CH_MAX; i++) { + struct chan *out = &cpu->ch[i]; + long type = pvt_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_threads(struct emu *emu) +{ + struct system *sys = &emu->system; + + /* Get thread PRV */ + struct pvt *pvt = recorder_find_pvt(&emu->recorder, "thread"); + if (pvt == NULL) { + err("cannot find thread pvt"); + return -1; + } + + /* Connect thread channels to PRV */ + 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; + } + } + + /* Init thread PCF */ + struct pcf *pcf = pvt_get_pcf(pvt); + if (init_pcf(pcf, CT_TH) != 0) { + err("init_pcf failed"); + return -1; + } + + return 0; +} + +static int +connect_cpus(struct emu *emu) +{ + struct system *sys = &emu->system; + + /* Get cpu PRV */ + struct pvt *pvt = recorder_find_pvt(&emu->recorder, "cpu"); + if (pvt == NULL) { + err("cannot find cpu pvt"); + return -1; + } + + /* Connect CPU channels to PRV */ + 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; + } + } + + /* Init CPU PCF */ + struct pcf *pcf = pvt_get_pcf(pvt); + if (init_pcf(pcf, CT_CPU) != 0) { + err("init_pcf failed"); + return -1; + } + + return 0; +} + +/* Connect all outputs to the paraver trace and setup PCF types */ +int +nosv_init_pvt(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; +} + +int +nosv_finish_pvt(struct emu *emu) +{ + struct system *sys = &emu->system; + + /* Emit task types for all channel types and processes */ + for (enum chan_type ct = 0; ct < CHAN_MAXTYPE; ct++) { + struct pvt *pvt = recorder_find_pvt(&emu->recorder, pvt_name[ct]); + if (pvt == NULL) { + err("cannot find pvt with name '%s'", pvt_name[ct]); + return -1; + } + struct pcf *pcf = pvt_get_pcf(pvt); + long typeid = pvt_type[CH_TYPE]; + struct pcf_type *pcftype = pcf_find_type(pcf, typeid); + + for (struct proc *p = sys->procs; p; p = p->gnext) { + struct nosv_proc *nosvproc = EXT(p, 'V'); + struct task_info *info = &nosvproc->task_info; + if (task_create_pcf_types(pcftype, info->types) != 0) { + err("task_create_pcf_types failed"); + return -1; + } + } + } + + return 0; +} + +const char * +nosv_ss_name(int ss) +{ + static const char *unknown = "(unknown)"; + const char *name = unknown; + const struct pcf_value_label *pv; + for (pv = &nosv_ss_values[0]; pv->label; pv++) { + if (pv->value == ss) { + name = pv->label; + break; + } + } + + return name; +} diff --git a/src/emu/ovni/event.c b/src/emu/ovni/event.c index 1e9c286..6abaa0e 100644 --- a/src/emu/ovni/event.c +++ b/src/emu/ovni/event.c @@ -307,6 +307,22 @@ pre_affinity(struct emu *emu) return 0; } +static int +pre_cpu(struct emu *emu) +{ + switch (emu->ev->v) { + case 'n': + err("ignoring old event OCn"); + return 0; + default: + err("unknown cpu event value %c\n", + emu->ev->v); + return -1; + } + + return 0; +} + static int compare_int64(const void *a, const void *b) { @@ -402,8 +418,9 @@ process_ev(struct emu *emu) case 'A': return pre_affinity(emu); case 'B': - pre_burst(emu); - break; + return pre_burst(emu); + case 'C': + return pre_cpu(emu); case 'F': return pre_flush(emu); default: diff --git a/src/emu/pv/pcf.c b/src/emu/pv/pcf.c index 8b95c3e..eac4960 100644 --- a/src/emu/pv/pcf.c +++ b/src/emu/pv/pcf.c @@ -92,32 +92,6 @@ const int pcf_palette_len = ARRAY_LEN(pcf_def_palette); // { -1, NULL }, //}; // -//struct pcf_value_label nosv_ss_values[] = { -// /* Errors */ -// { ST_BAD, "Unknown: bad happened (report bug)" }, -// { ST_TOO_MANY_TH, "Unknown: multiple threads running" }, -// /* Good values */ -// { ST_NULL, "No subsystem" }, -// { ST_NOSV_SCHED_HUNGRY, "Scheduler: Hungry" }, -// { ST_NOSV_SCHED_SERVING, "Scheduler: Serving" }, -// { ST_NOSV_SCHED_SUBMITTING, "Scheduler: Submitting" }, -// { ST_NOSV_MEM_ALLOCATING, "Memory: Allocating" }, -// { ST_NOSV_MEM_FREEING, "Memory: Freeing" }, -// { ST_NOSV_TASK_RUNNING, "Task: Running" }, -// { ST_NOSV_API_SUBMIT, "API: Submit" }, -// { ST_NOSV_API_PAUSE, "API: Pause" }, -// { ST_NOSV_API_YIELD, "API: Yield" }, -// { ST_NOSV_API_WAITFOR, "API: Waitfor" }, -// { ST_NOSV_API_SCHEDPOINT, "API: Scheduling point" }, -// { ST_NOSV_ATTACH, "Thread: Attached" }, -// { ST_NOSV_WORKER, "Thread: Worker" }, -// { ST_NOSV_DELEGATE, "Thread: Delegate" }, -// { EV_NOSV_SCHED_SEND, "EV Scheduler: Send task" }, -// { EV_NOSV_SCHED_RECV, "EV Scheduler: Recv task" }, -// { EV_NOSV_SCHED_SELF, "EV Scheduler: Self-assign task" }, -// { -1, NULL }, -//}; -// //struct pcf_value_label nodes_mode_values[] = { // { ST_NULL, "NULL" }, // { ST_TOO_MANY_TH, "NODES: Multiple threads running" }, diff --git a/test/emu/CMakeLists.txt b/test/emu/CMakeLists.txt index 479c36b..cdc3cc4 100644 --- a/test/emu/CMakeLists.txt +++ b/test/emu/CMakeLists.txt @@ -2,5 +2,5 @@ # SPDX-License-Identifier: GPL-3.0-or-later add_subdirectory(ovni) -#add_subdirectory(nosv) +add_subdirectory(nosv) add_subdirectory(nanos6) diff --git a/test/emu/nosv/CMakeLists.txt b/test/emu/nosv/CMakeLists.txt index 5618a11..0ab9bf4 100644 --- a/test/emu/nosv/CMakeLists.txt +++ b/test/emu/nosv/CMakeLists.txt @@ -3,7 +3,7 @@ ovni_test(nested-tasks.c) ovni_test(nested-tasks-bad.c SHOULD_FAIL - REGEX "fatal: cannot execute task 1: state is not created") + REGEX "cannot execute task 1: state is not created") ovni_test(task-types.c MP) ovni_test(pause.c MP) ovni_test(mp-rank.c MP) diff --git a/test/rt/CMakeLists.txt b/test/rt/CMakeLists.txt index dffe718..0945b87 100644 --- a/test/rt/CMakeLists.txt +++ b/test/rt/CMakeLists.txt @@ -3,4 +3,4 @@ add_subdirectory(nanos6) #add_subdirectory(nodes) -#add_subdirectory(nosv) +add_subdirectory(nosv) diff --git a/test/rt/nosv/CMakeLists.txt b/test/rt/nosv/CMakeLists.txt index 6903e77..ba660e0 100644 --- a/test/rt/nosv/CMakeLists.txt +++ b/test/rt/nosv/CMakeLists.txt @@ -23,6 +23,6 @@ function(nosv_test) ENVIRONMENT "NOSV_CONFIG=${OVNI_TEST_SOURCE_DIR}/rt/nosv/nosv.toml") endfunction() -nosv_test(attach.c SORT) -nosv_test(waitfor.c SORT) -nosv_test(several-tasks.c SORT) +nosv_test(attach.c) +nosv_test(waitfor.c) +nosv_test(several-tasks.c) diff --git a/test/unit/loom.c b/test/unit/loom.c index ac69f85..cd414e2 100644 --- a/test/unit/loom.c +++ b/test/unit/loom.c @@ -41,7 +41,7 @@ test_negative_cpu(struct loom *loom) die("loom_init_begin failed"); struct cpu cpu; - cpu_init_begin(&cpu, -1); + cpu_init_begin(&cpu, -1, 0); if (loom_add_cpu(loom, &cpu) == 0) die("loom_add_cpu didn't fail"); @@ -56,7 +56,7 @@ test_duplicate_cpus(struct loom *loom) die("loom_init_begin failed"); struct cpu cpu; - cpu_init_begin(&cpu, 123); + cpu_init_begin(&cpu, 123, 0); if (loom_add_cpu(loom, &cpu) != 0) die("loom_add_cpu failed");