Use the track module in nOS-V too

This commit is contained in:
Rodrigo Arias 2023-02-13 19:32:03 +01:00 committed by Rodrigo Arias Mallo
parent 259de4df43
commit e471930fd5
9 changed files with 134 additions and 207 deletions

View File

@ -1,32 +1,28 @@
#include "nanos6_priv.h" #include "nanos6_priv.h"
const int nanos6_chan_track[CH_MAX][CT_MAX] = { static const int th_track[CH_MAX] = {
/* Thread CPU */ [CH_TASKID] = TRACK_TH_RUN,
[CH_TASKID] = { TRACK_TH_RUN, TRACK_TH_RUN }, [CH_TYPE] = TRACK_TH_RUN,
[CH_TYPE] = { TRACK_TH_RUN, TRACK_TH_RUN }, [CH_SUBSYSTEM] = TRACK_TH_ACT,
[CH_SUBSYSTEM] = { TRACK_TH_ACT, TRACK_TH_RUN }, [CH_RANK] = TRACK_TH_RUN,
[CH_RANK] = { TRACK_TH_RUN, TRACK_TH_RUN }, [CH_THREAD] = TRACK_TH_ANY,
[CH_THREAD] = { TRACK_TH_ANY, TRACK_TH_RUN },
}; };
static int static const int cpu_track[CH_MAX] = {
connect_thread(struct thread *sth) [CH_TASKID] = TRACK_TH_RUN,
[CH_TYPE] = TRACK_TH_RUN,
[CH_SUBSYSTEM] = TRACK_TH_RUN,
[CH_RANK] = TRACK_TH_RUN,
[CH_THREAD] = TRACK_TH_RUN,
};
int
nanos6_get_track(enum nanos6_chan c, enum nanos6_chan_type type)
{ {
struct nanos6_thread *th = EXT(sth, '6'); if (type == CT_TH)
return th_track[c];
for (int i = 0; i < CH_MAX; i++) { else
struct track *track = &th->track[i]; return cpu_track[c];
if (track_thread(track, &sth->chan[TH_CHAN_STATE], &th->ch[i]) != 0) {
err("track_thread failed");
return -1;
}
/* Select the default output to PRV */
track_set_default(track, nanos6_chan_track[i][CT_TH]);
}
return 0;
} }
static int static int
@ -34,13 +30,13 @@ connect_cpu(struct emu *emu, struct cpu *scpu)
{ {
struct nanos6_cpu *cpu = EXT(scpu, '6'); struct nanos6_cpu *cpu = EXT(scpu, '6');
for (int i = 0; i < CH_MAX; i++) { for (int i = 0; i < CH_MAX; i++) {
struct track *cpu_track = &cpu->track[i]; struct track *track = &cpu->track[i];
/* Choose select CPU channel based on tracking mode (only /* Choose select CPU channel based on tracking mode (only
* TRACK_TH_RUN allowed, as active may cause collisions) */ * TRACK_TH_RUN allowed, as active may cause collisions) */
int mode = nanos6_chan_track[i][CT_CPU]; int mode = nanos6_get_track(i, CT_CPU);
struct chan *sel = cpu_get_th_chan(scpu, mode); struct chan *sel = cpu_get_th_chan(scpu, mode);
if (track_set_select(cpu_track, mode, sel, NULL) != 0) { if (track_set_select(track, mode, sel, NULL) != 0) {
err("track_select failed"); err("track_select failed");
return -1; return -1;
} }
@ -54,14 +50,14 @@ connect_cpu(struct emu *emu, struct cpu *scpu)
struct value key = value_int64(t->gindex); struct value key = value_int64(t->gindex);
struct chan *inp = track_get_output(&th->track[i], mode); struct chan *inp = track_get_output(&th->track[i], mode);
if (track_add_input(cpu_track, mode, key, inp) != 0) { if (track_add_input(track, mode, key, inp) != 0) {
err("track_add_input failed"); err("track_add_input failed");
return -1; return -1;
} }
} }
/* Set the PRV output */ /* Set the PRV output */
track_set_default(cpu_track, nanos6_chan_track[i][CT_CPU]); track_set_default(track, nanos6_get_track(i, CT_CPU));
} }
return 0; return 0;
@ -74,8 +70,10 @@ nanos6_connect(struct emu *emu)
/* threads */ /* threads */
for (struct thread *t = sys->threads; t; t = t->gnext) { for (struct thread *t = sys->threads; t; t = t->gnext) {
if (connect_thread(t) != 0) { struct nanos6_thread *th = EXT(t, '6');
err("connect_thread failed"); struct chan *sel = &t->chan[TH_CHAN_STATE];
if (track_connect_thread(th->track, th->ch, th_track, sel, CH_MAX) != 0) {
err("track_thread failed");
return -1; return -1;
} }
} }

View File

@ -27,8 +27,6 @@ enum nanos6_chan {
CH_MAX, CH_MAX,
}; };
extern const int nanos6_chan_track[CH_MAX][CT_MAX];
enum nanos6_ss_state { enum nanos6_ss_state {
ST_TASK_BODY = 1, ST_TASK_BODY = 1,
ST_TASK_CREATING, ST_TASK_CREATING,
@ -92,5 +90,6 @@ int nanos6_finish(struct emu *emu);
int nanos6_init_pvt(struct emu *emu); int nanos6_init_pvt(struct emu *emu);
int nanos6_finish_pvt(struct emu *emu); int nanos6_finish_pvt(struct emu *emu);
const char *nanos6_ss_name(int ss); const char *nanos6_ss_name(int ss);
int nanos6_get_track(enum nanos6_chan c, enum nanos6_chan_type type);
#endif /* NANOS6_PRIV_H */ #endif /* NANOS6_PRIV_H */

View File

@ -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 */ /* Compute the label by joining the two parts */
const char *prefix = pcf_prefix[c]; const char *prefix = pcf_prefix[c];
int track_mode = nanos6_chan_track[c][ct]; int track_mode = nanos6_get_track(c, ct);
const char *suffix = pcf_suffix[track_mode]; const char *suffix = pcf_suffix[track_mode];
char label[MAX_PCF_LABEL]; char label[MAX_PCF_LABEL];

View File

@ -1,122 +1,65 @@
#include "nosv_priv.h" #include "nosv_priv.h"
const enum nosv_track nosv_chan_track[CH_MAX][CT_MAX] = { static const int th_track[CH_MAX] = {
/* Thread CPU */ [CH_TASKID] = TRACK_TH_RUN,
[CH_TASKID] = { RUN_TH, RUN_TH }, [CH_TYPE] = TRACK_TH_RUN,
[CH_TYPE] = { RUN_TH, RUN_TH }, [CH_APPID] = TRACK_TH_RUN,
[CH_APPID] = { RUN_TH, RUN_TH }, [CH_SUBSYSTEM] = TRACK_TH_ACT,
[CH_SUBSYSTEM] = { ACT_TH, RUN_TH }, [CH_RANK] = TRACK_TH_RUN,
[CH_RANK] = { RUN_TH, RUN_TH },
}; };
static const int cpu_track[CH_MAX] = {
[CH_TASKID] = TRACK_TH_RUN,
[CH_TYPE] = TRACK_TH_RUN,
[CH_APPID] = TRACK_TH_RUN,
[CH_SUBSYSTEM] = TRACK_TH_RUN,
[CH_RANK] = TRACK_TH_RUN,
};
static int int
connect_thread_mux(struct emu *emu, struct thread *thread) nosv_get_track(int c, int type)
{ {
struct nosv_thread *th = EXT(thread, 'V'); if (type == CT_TH)
for (int i = 0; i < CH_MAX; i++) { return th_track[c];
/* 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 else
th->ch_out[i] = &th->ch[i]; return cpu_track[c];
}
return 0;
} }
static int static int
add_inputs_cpu_mux(struct emu *emu, struct mux *mux, int i) connect_cpu(struct emu *emu, struct cpu *scpu)
{
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'); struct nosv_cpu *cpu = EXT(scpu, 'V');
for (int i = 0; i < CH_MAX; i++) { for (int i = 0; i < CH_MAX; i++) {
struct mux *mux = &cpu->mux[i]; struct track *track = &cpu->track[i];
struct chan *out = &cpu->ch[i];
/* Choose select CPU channel based on tracking mode */ /* Choose select CPU channel based on tracking mode (only
struct chan *sel = NULL; * TRACK_TH_RUN allowed, as active may cause collisions) */
enum nosv_track track = nosv_chan_track[i][CT_CPU]; int mode = nosv_get_track(i, CT_CPU);
if (track == RUN_TH) struct chan *sel = cpu_get_th_chan(scpu, mode);
sel = &scpu->chan[CPU_CHAN_THRUN]; if (track_set_select(track, mode, sel, NULL) != 0) {
else if (track == ACT_TH) err("track_select failed");
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; return -1;
} }
if (add_inputs_cpu_mux(emu, mux, i) != 0) { /* Add each thread as input */
err("add_inputs_cpu_mux failed"); for (struct thread *t = emu->system.threads; t; t = t->gnext) {
struct nosv_thread *th = EXT(t, 'V');
/* Choose input channel from the thread output channels
* based on CPU tracking mode */
struct value key = value_int64(t->gindex);
struct chan *inp = track_get_output(&th->track[i], mode);
if (track_add_input(track, mode, key, inp) != 0) {
err("track_add_input failed");
return -1; return -1;
} }
} }
/* Set the PRV output */
track_set_default(track, nosv_get_track(i, CT_CPU));
}
return 0; return 0;
} }
@ -127,16 +70,18 @@ nosv_connect(struct emu *emu)
/* threads */ /* threads */
for (struct thread *t = sys->threads; t; t = t->gnext) { for (struct thread *t = sys->threads; t; t = t->gnext) {
if (connect_thread_mux(emu, t) != 0) { struct nosv_thread *th = EXT(t, 'V');
err("connect_thread_mux failed"); struct chan *sel = &t->chan[TH_CHAN_STATE];
if (track_connect_thread(th->track, th->ch, th_track, sel, CH_MAX) != 0) {
err("track_thread failed");
return -1; return -1;
} }
} }
/* cpus */ /* cpus */
for (struct cpu *c = sys->cpus; c; c = c->next) { for (struct cpu *c = sys->cpus; c; c = c->next) {
if (connect_cpu_mux(emu, c) != 0) { if (connect_cpu(emu, c) != 0) {
err("connect_cpu_mux failed"); err("connect_cpu failed");
return -1; return -1;
} }
} }

View File

@ -1,12 +1,5 @@
#include "nosv_priv.h" #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] = { static const char *chan_name[CH_MAX] = {
[CH_TASKID] = "taskid", [CH_TASKID] = "taskid",
[CH_TYPE] = "task_type", [CH_TYPE] = "task_type",
@ -20,11 +13,11 @@ static const int chan_stack[CH_MAX] = {
}; };
static int static int
init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex, int filtered) init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex)
{ {
for (int i = 0; i < CH_MAX; i++) { for (int i = 0; i < CH_MAX; i++) {
struct chan *c = &chans[i]; struct chan *c = &chans[i];
int type = (chan_stack[i] && !filtered) ? CHAN_STACK : CHAN_SINGLE; int type = chan_stack[i];
chan_init(c, type, fmt, gindex, chan_name[i]); chan_init(c, type, fmt, gindex, chan_name[i]);
if (bay_register(bay, c) != 0) { if (bay_register(bay, c) != 0) {
@ -36,6 +29,21 @@ init_chans(struct bay *bay, struct chan *chans, const char *fmt, int64_t gindex,
return 0; return 0;
} }
static int
init_tracks(struct bay *bay, struct track *tracks, const char *fmt, int64_t gindex)
{
for (int i = 0; i < CH_MAX; i++) {
struct track *track = &tracks[i];
if (track_init(track, bay, TRACK_TYPE_TH, fmt, gindex, chan_name[i]) != 0) {
err("track_init failed");
return -1;
}
}
return 0;
}
static int static int
init_cpu(struct bay *bay, struct cpu *syscpu) init_cpu(struct bay *bay, struct cpu *syscpu)
{ {
@ -45,19 +53,14 @@ init_cpu(struct bay *bay, struct cpu *syscpu)
return -1; return -1;
} }
cpu->ch = calloc(CH_MAX, sizeof(struct chan)); cpu->track = calloc(CH_MAX, sizeof(struct track));
if (cpu->ch == NULL) { if (cpu->track == NULL) {
err("calloc failed:"); err("calloc failed:");
return -1; return -1;
} }
cpu->mux = calloc(CH_MAX, sizeof(struct mux)); char *fmt = "nosv.cpu%ld.%s";
if (cpu->mux == NULL) { if (init_tracks(bay, cpu->track, fmt, syscpu->gindex) != 0) {
err("calloc failed:");
return -1;
}
if (init_chans(bay, cpu->ch, chan_fmt_cpu_raw, syscpu->gindex, 1) != 0) {
err("init_chans failed"); err("init_chans failed");
return -1; return -1;
} }
@ -81,52 +84,23 @@ init_thread(struct bay *bay, struct thread *systh)
return -1; return -1;
} }
th->ch_run = calloc(CH_MAX, sizeof(struct chan)); th->track = calloc(CH_MAX, sizeof(struct track));
if (th->ch_run == NULL) { if (th->track == NULL) {
err("calloc failed:"); err("calloc failed:");
return -1; return -1;
} }
th->ch_act = calloc(CH_MAX, sizeof(struct chan)); char *fmt = "nosv.thread%ld.%s";
if (th->ch_act == NULL) { if (init_chans(bay, th->ch, fmt, systh->gindex) != 0) {
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"); err("init_chans failed");
return -1; return -1;
} }
if (init_chans(bay, th->ch_run, chan_fmt_th_run, systh->gindex, 1) != 0) { if (init_tracks(bay, th->track, fmt, systh->gindex) != 0) {
err("init_chans failed"); err("init_tracks failed");
return -1; 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; th->task_stack.thread = systh;
extend_set(&systh->ext, 'V', th); extend_set(&systh->ext, 'V', th);

View File

@ -33,8 +33,6 @@ enum nosv_track {
TRACK_MAX, TRACK_MAX,
}; };
extern const enum nosv_track nosv_chan_track[CH_MAX][CT_MAX];
enum nosv_ss_values { enum nosv_ss_values {
ST_SCHED_HUNGRY = 6, ST_SCHED_HUNGRY = 6,
ST_SCHED_SERVING, ST_SCHED_SERVING,
@ -57,18 +55,13 @@ enum nosv_ss_values {
}; };
struct nosv_thread { struct nosv_thread {
struct chan *ch; /* Raw, modified by nosv */ struct chan *ch;
struct chan *ch_run; /* Tracking running thread */ struct track *track;
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 task_stack task_stack;
}; };
struct nosv_cpu { struct nosv_cpu {
struct chan *ch; struct track *track;
struct mux *mux;
}; };
struct nosv_proc { struct nosv_proc {
@ -84,5 +77,6 @@ int nosv_finish(struct emu *emu);
int nosv_init_pvt(struct emu *emu); int nosv_init_pvt(struct emu *emu);
int nosv_finish_pvt(struct emu *emu); int nosv_finish_pvt(struct emu *emu);
const char *nosv_ss_name(int ss); const char *nosv_ss_name(int ss);
int nosv_get_track(int c, int type);
#endif /* NOSV_PRIV_H */ #endif /* NOSV_PRIV_H */

View File

@ -81,7 +81,7 @@ create_type(struct pcf *pcf, enum nosv_chan c, enum nosv_chan_type ct)
/* Compute the label by joining the two parts */ /* Compute the label by joining the two parts */
const char *prefix = pcf_prefix[c]; const char *prefix = pcf_prefix[c];
int track_mode = nosv_chan_track[c][ct]; int track_mode = nosv_get_track(c, ct);
const char *suffix = pcf_suffix[track_mode]; const char *suffix = pcf_suffix[track_mode];
char label[MAX_PCF_LABEL]; char label[MAX_PCF_LABEL];
@ -119,7 +119,7 @@ connect_thread_prv(struct emu *emu, struct thread *thread, struct prv *prv)
{ {
struct nosv_thread *th = EXT(thread, 'V'); struct nosv_thread *th = EXT(thread, 'V');
for (int i = 0; i < CH_MAX; i++) { for (int i = 0; i < CH_MAX; i++) {
struct chan *out = th->ch_out[i]; struct chan *out = track_get_default(&th->track[i]);
long type = pvt_type[i]; long type = pvt_type[i];
long row = thread->gindex; long row = thread->gindex;
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {
@ -136,7 +136,7 @@ connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv)
{ {
struct nosv_cpu *cpu = EXT(scpu, 'V'); struct nosv_cpu *cpu = EXT(scpu, 'V');
for (int i = 0; i < CH_MAX; i++) { for (int i = 0; i < CH_MAX; i++) {
struct chan *out = &cpu->ch[i]; struct chan *out = track_get_default(&cpu->track[i]);
long type = pvt_type[i]; long type = pvt_type[i];
long row = scpu->gindex; long row = scpu->gindex;
if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) {

View File

@ -106,8 +106,8 @@ track_add_input(struct track *track, int mode, struct value key, struct chan *in
return 0; return 0;
} }
int static int
track_thread(struct track *track, struct chan *sel, struct chan *inp) track_th_input_chan(struct track *track, struct chan *sel, struct chan *inp)
{ {
/* Create all thread tracking modes */ /* Create all thread tracking modes */
if (track_set_select(track, TRACK_TH_ANY, sel, thread_select_any) != 0) { if (track_set_select(track, TRACK_TH_ANY, sel, thread_select_any) != 0) {
@ -138,3 +138,20 @@ track_thread(struct track *track, struct chan *sel, struct chan *inp)
return 0; return 0;
} }
int
track_connect_thread(struct track *tracks, struct chan *chans, const int *modes, struct chan *sel, int n)
{
for (int i = 0; i < n; i++) {
struct track *track = &tracks[i];
if (track_th_input_chan(track, sel, &chans[i]) != 0) {
err("track_th_input_chan failed");
return -1;
}
/* Select the default output to PRV */
track_set_default(track, modes[i]);
}
return 0;
}

View File

@ -37,6 +37,6 @@ void track_set_default(struct track *track, int mode);
struct chan *track_get_default(struct track *track); struct chan *track_get_default(struct track *track);
struct chan *track_get_output(struct track *track, int mode); struct chan *track_get_output(struct track *track, int mode);
int track_thread(struct track *track, struct chan *sel, struct chan *inp); int track_connect_thread(struct track *tracks, struct chan *chans, const int *modes, struct chan *sel, int n);
#endif /* TRACK_H */ #endif /* TRACK_H */