diff --git a/src/emu/nanos6/connect.c b/src/emu/nanos6/connect.c index e797b84..06dc4b0 100644 --- a/src/emu/nanos6/connect.c +++ b/src/emu/nanos6/connect.c @@ -1,32 +1,28 @@ #include "nanos6_priv.h" -const int nanos6_chan_track[CH_MAX][CT_MAX] = { - /* Thread CPU */ - [CH_TASKID] = { TRACK_TH_RUN, TRACK_TH_RUN }, - [CH_TYPE] = { TRACK_TH_RUN, TRACK_TH_RUN }, - [CH_SUBSYSTEM] = { TRACK_TH_ACT, TRACK_TH_RUN }, - [CH_RANK] = { TRACK_TH_RUN, TRACK_TH_RUN }, - [CH_THREAD] = { TRACK_TH_ANY, TRACK_TH_RUN }, +static const int th_track[CH_MAX] = { + [CH_TASKID] = TRACK_TH_RUN, + [CH_TYPE] = TRACK_TH_RUN, + [CH_SUBSYSTEM] = TRACK_TH_ACT, + [CH_RANK] = TRACK_TH_RUN, + [CH_THREAD] = TRACK_TH_ANY, }; -static int -connect_thread(struct thread *sth) +static const int cpu_track[CH_MAX] = { + [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'); - - for (int i = 0; i < CH_MAX; i++) { - struct track *track = &th->track[i]; - - 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; + if (type == CT_TH) + return th_track[c]; + else + return cpu_track[c]; } static int @@ -34,13 +30,13 @@ connect_cpu(struct emu *emu, struct cpu *scpu) { struct nanos6_cpu *cpu = EXT(scpu, '6'); 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 * 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); - if (track_set_select(cpu_track, mode, sel, NULL) != 0) { + if (track_set_select(track, mode, sel, NULL) != 0) { err("track_select failed"); return -1; } @@ -54,14 +50,14 @@ connect_cpu(struct emu *emu, struct cpu *scpu) struct value key = value_int64(t->gindex); 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"); return -1; } } /* 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; @@ -74,8 +70,10 @@ nanos6_connect(struct emu *emu) /* threads */ for (struct thread *t = sys->threads; t; t = t->gnext) { - if (connect_thread(t) != 0) { - err("connect_thread failed"); + struct nanos6_thread *th = EXT(t, '6'); + 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; } } diff --git a/src/emu/nanos6/nanos6_priv.h b/src/emu/nanos6/nanos6_priv.h index 4f3ca87..fdd6210 100644 --- a/src/emu/nanos6/nanos6_priv.h +++ b/src/emu/nanos6/nanos6_priv.h @@ -27,8 +27,6 @@ enum nanos6_chan { CH_MAX, }; -extern const int nanos6_chan_track[CH_MAX][CT_MAX]; - enum nanos6_ss_state { ST_TASK_BODY = 1, ST_TASK_CREATING, @@ -92,5 +90,6 @@ int nanos6_finish(struct emu *emu); int nanos6_init_pvt(struct emu *emu); int nanos6_finish_pvt(struct emu *emu); const char *nanos6_ss_name(int ss); +int nanos6_get_track(enum nanos6_chan c, enum nanos6_chan_type type); #endif /* NANOS6_PRIV_H */ diff --git a/src/emu/nanos6/pvt.c b/src/emu/nanos6/pvt.c index 0087631..3c321cc 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 = nanos6_chan_track[c][ct]; + int track_mode = nanos6_get_track(c, ct); const char *suffix = pcf_suffix[track_mode]; char label[MAX_PCF_LABEL]; diff --git a/src/emu/nosv/connect.c b/src/emu/nosv/connect.c index 7529ca2..6b6c7e9 100644 --- a/src/emu/nosv/connect.c +++ b/src/emu/nosv/connect.c @@ -1,120 +1,63 @@ #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 const int th_track[CH_MAX] = { + [CH_TASKID] = TRACK_TH_RUN, + [CH_TYPE] = TRACK_TH_RUN, + [CH_APPID] = TRACK_TH_RUN, + [CH_SUBSYSTEM] = TRACK_TH_ACT, + [CH_RANK] = TRACK_TH_RUN, }; +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 -connect_thread_mux(struct emu *emu, struct thread *thread) +int +nosv_get_track(int c, int type) { - 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; + if (type == CT_TH) + return th_track[c]; + else + return cpu_track[c]; } 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) +connect_cpu(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]; + struct track *track = &cpu->track[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"); + /* Choose select CPU channel based on tracking mode (only + * TRACK_TH_RUN allowed, as active may cause collisions) */ + int mode = nosv_get_track(i, CT_CPU); + struct chan *sel = cpu_get_th_chan(scpu, mode); + if (track_set_select(track, mode, sel, NULL) != 0) { + err("track_select failed"); return -1; } - if (add_inputs_cpu_mux(emu, mux, i) != 0) { - err("add_inputs_cpu_mux failed"); - return -1; + /* Add each thread as input */ + 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; + } } + + /* Set the PRV output */ + track_set_default(track, nosv_get_track(i, CT_CPU)); } return 0; @@ -127,16 +70,18 @@ nosv_connect(struct emu *emu) /* threads */ for (struct thread *t = sys->threads; t; t = t->gnext) { - if (connect_thread_mux(emu, t) != 0) { - err("connect_thread_mux failed"); + struct nosv_thread *th = EXT(t, 'V'); + 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; } } /* cpus */ for (struct cpu *c = sys->cpus; c; c = c->next) { - if (connect_cpu_mux(emu, c) != 0) { - err("connect_cpu_mux failed"); + if (connect_cpu(emu, c) != 0) { + err("connect_cpu failed"); return -1; } } diff --git a/src/emu/nosv/create.c b/src/emu/nosv/create.c index 03c5c31..77303f3 100644 --- a/src/emu/nosv/create.c +++ b/src/emu/nosv/create.c @@ -1,12 +1,5 @@ #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", @@ -20,11 +13,11 @@ static const int chan_stack[CH_MAX] = { }; 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++) { 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]); 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; } +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 init_cpu(struct bay *bay, struct cpu *syscpu) { @@ -45,19 +53,14 @@ init_cpu(struct bay *bay, struct cpu *syscpu) return -1; } - cpu->ch = calloc(CH_MAX, sizeof(struct chan)); - if (cpu->ch == NULL) { + cpu->track = calloc(CH_MAX, sizeof(struct track)); + if (cpu->track == 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) { + char *fmt = "nosv.cpu%ld.%s"; + if (init_tracks(bay, cpu->track, fmt, syscpu->gindex) != 0) { err("init_chans failed"); return -1; } @@ -81,52 +84,23 @@ init_thread(struct bay *bay, struct thread *systh) return -1; } - th->ch_run = calloc(CH_MAX, sizeof(struct chan)); - if (th->ch_run == NULL) { + th->track = calloc(CH_MAX, sizeof(struct track)); + if (th->track == 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) { + char *fmt = "nosv.thread%ld.%s"; + if (init_chans(bay, th->ch, fmt, systh->gindex) != 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"); + if (init_tracks(bay, th->track, fmt, systh->gindex) != 0) { + err("init_tracks 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); diff --git a/src/emu/nosv/nosv_priv.h b/src/emu/nosv/nosv_priv.h index 9a28c05..4fd19b3 100644 --- a/src/emu/nosv/nosv_priv.h +++ b/src/emu/nosv/nosv_priv.h @@ -33,8 +33,6 @@ enum nosv_track { 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, @@ -57,18 +55,13 @@ enum nosv_ss_values { }; 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 chan *ch; + struct track *track; struct task_stack task_stack; }; struct nosv_cpu { - struct chan *ch; - struct mux *mux; + struct track *track; }; struct nosv_proc { @@ -84,5 +77,6 @@ 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); +int nosv_get_track(int c, int type); #endif /* NOSV_PRIV_H */ diff --git a/src/emu/nosv/pvt.c b/src/emu/nosv/pvt.c index 9a5b0c5..7513855 100644 --- a/src/emu/nosv/pvt.c +++ b/src/emu/nosv/pvt.c @@ -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 */ 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]; 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'); 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 row = thread->gindex; 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'); 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 row = scpu->gindex; if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { diff --git a/src/emu/track.c b/src/emu/track.c index 5b8f3da..cd38ef0 100644 --- a/src/emu/track.c +++ b/src/emu/track.c @@ -106,8 +106,8 @@ track_add_input(struct track *track, int mode, struct value key, struct chan *in return 0; } -int -track_thread(struct track *track, struct chan *sel, struct chan *inp) +static int +track_th_input_chan(struct track *track, struct chan *sel, struct chan *inp) { /* Create all thread tracking modes */ 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; } +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; +} diff --git a/src/emu/track.h b/src/emu/track.h index b91f245..985546d 100644 --- a/src/emu/track.h +++ b/src/emu/track.h @@ -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_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 */