diff --git a/src/emu/cpu.c b/src/emu/cpu.c index 85d15b8..bd3edf0 100644 --- a/src/emu/cpu.c +++ b/src/emu/cpu.c @@ -26,6 +26,12 @@ static int chan_type[] = { [CPU_CHAN_THACT] = -1, }; +static long chan_flags[] = { + [CPU_CHAN_PID] = PRV_SKIPDUP, + [CPU_CHAN_TID] = PRV_SKIPDUP, + [CPU_CHAN_NRUN] = PRV_SKIPDUP | PRV_ZERO, +}; + void cpu_init_begin(struct cpu *cpu, int index, int phyid, int is_virtual) { @@ -148,7 +154,8 @@ cpu_connect(struct cpu *cpu, struct bay *bay, struct recorder *rec) continue; long row = cpu->gindex; - if (prv_register(prv, row, type, bay, c, PRV_DUP)) { + long flags = chan_flags[i]; + if (prv_register(prv, row, type, bay, c, flags)) { err("prv_register failed"); return -1; } diff --git a/src/emu/kernel/setup.c b/src/emu/kernel/setup.c index f3d950f..02a723a 100644 --- a/src/emu/kernel/setup.c +++ b/src/emu/kernel/setup.c @@ -41,10 +41,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { [CH_CS] = &kernel_cs_values, }; +static const long prv_flags[CH_MAX] = { + [CH_CS] = PRV_SKIPDUP, +}; + static const struct model_pvt_spec pvt_spec = { .type = pvt_type, .prefix = pcf_prefix, .label = pcf_labels, + .flags = prv_flags, }; /* ----------------- tracking ------------------ */ diff --git a/src/emu/model_pvt.c b/src/emu/model_pvt.c index 89a19ad..21b6267 100644 --- a/src/emu/model_pvt.c +++ b/src/emu/model_pvt.c @@ -75,11 +75,13 @@ connect_cpu_prv(struct emu *emu, struct cpu *scpu, struct prv *prv, int id) { struct model_cpu *cpu = EXT(scpu, id); const struct model_chan_spec *spec = cpu->spec->chan; + const long *flags_arr = spec->pvt->flags; for (int i = 0; i < spec->nch; i++) { struct chan *out = track_get_output(&cpu->track[i]); long type = spec->pvt->type[i]; long row = scpu->gindex; - if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { + long flags = flags_arr ? flags_arr[i] : 0; + if (prv_register(prv, row, type, &emu->bay, out, flags)) { err("prv_register failed"); return -1; } @@ -125,11 +127,13 @@ connect_thread_prv(struct emu *emu, struct thread *sth, struct prv *prv, int id) { struct model_thread *th = EXT(sth, id); const struct model_chan_spec *spec = th->spec->chan; + const long *flags_arr = spec->pvt->flags; for (int i = 0; i < spec->nch; i++) { struct chan *out = track_get_output(&th->track[i]); long type = spec->pvt->type[i]; long row = sth->gindex; - if (prv_register(prv, row, type, &emu->bay, out, PRV_DUP)) { + long flags = flags_arr ? flags_arr[i] : 0; + if (prv_register(prv, row, type, &emu->bay, out, flags)) { err("prv_register failed"); return -1; } diff --git a/src/emu/model_pvt.h b/src/emu/model_pvt.h index f9cfb85..a944488 100644 --- a/src/emu/model_pvt.h +++ b/src/emu/model_pvt.h @@ -11,6 +11,7 @@ struct model_pvt_spec { const int *type; const char **prefix; const char **suffix; + const long *flags; const struct pcf_value_label (**label)[]; }; diff --git a/src/emu/nanos6/setup.c b/src/emu/nanos6/setup.c index eff5061..1193dc2 100644 --- a/src/emu/nanos6/setup.c +++ b/src/emu/nanos6/setup.c @@ -92,10 +92,19 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { [CH_THREAD] = &nanos6_thread_type, }; +static const long prv_flags[CH_MAX] = { + [CH_TASKID] = PRV_SKIPDUP, + [CH_TYPE] = PRV_SKIPDUP, + [CH_SUBSYSTEM] = PRV_SKIPDUP, + [CH_RANK] = PRV_SKIPDUP, + [CH_THREAD] = PRV_SKIPDUP, +}; + static const struct model_pvt_spec pvt_spec = { .type = pvt_type, .prefix = pcf_prefix, .label = pcf_labels, + .flags = prv_flags, }; /* ----------------- tracking ------------------ */ diff --git a/src/emu/nodes/setup.c b/src/emu/nodes/setup.c index 7cfcb4c..8f5b337 100644 --- a/src/emu/nodes/setup.c +++ b/src/emu/nodes/setup.c @@ -49,10 +49,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { [CH_SUBSYSTEM] = &nodes_ss_values, }; +static const long prv_flags[CH_MAX] = { + [CH_SUBSYSTEM] = PRV_SKIPDUP, +}; + static const struct model_pvt_spec pvt_spec = { .type = pvt_type, .prefix = pcf_prefix, .label = pcf_labels, + .flags = prv_flags, }; /* ----------------- tracking ------------------ */ diff --git a/src/emu/nosv/setup.c b/src/emu/nosv/setup.c index edad404..6f53447 100644 --- a/src/emu/nosv/setup.c +++ b/src/emu/nosv/setup.c @@ -75,10 +75,37 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { [CH_SUBSYSTEM] = &nosv_ss_values, }; -static const struct model_pvt_spec pvt_spec = { +/* ------------- duplicates in prv -------------- */ + +static const long th_prv_flags[CH_MAX] = { + /* Due muxes we need to skip duplicated nulls */ + [CH_TASKID] = PRV_SKIPDUP, + [CH_TYPE] = PRV_SKIPDUP, + [CH_APPID] = PRV_SKIPDUP, + [CH_SUBSYSTEM] = PRV_SKIPDUP, + [CH_RANK] = PRV_SKIPDUP, +}; + +static const long cpu_prv_flags[CH_MAX] = { + [CH_TASKID] = PRV_SKIPDUP, + [CH_TYPE] = PRV_SKIPDUP, + [CH_APPID] = PRV_SKIPDUP, + [CH_SUBSYSTEM] = PRV_SKIPDUP, + [CH_RANK] = PRV_SKIPDUP, +}; + +static const struct model_pvt_spec th_pvt_spec = { .type = pvt_type, .prefix = pcf_prefix, .label = pcf_labels, + .flags = th_prv_flags, +}; + +static const struct model_pvt_spec cpu_pvt_spec = { + .type = pvt_type, + .prefix = pcf_prefix, + .label = pcf_labels, + .flags = cpu_prv_flags, }; /* ----------------- tracking ------------------ */ @@ -107,7 +134,7 @@ static const struct model_chan_spec th_chan = { .ch_names = chan_name, .ch_stack = chan_stack, .ch_dup = chan_dup, - .pvt = &pvt_spec, + .pvt = &th_pvt_spec, .track = th_track, }; @@ -116,24 +143,24 @@ static const struct model_chan_spec cpu_chan = { .prefix = model_name, .ch_names = chan_name, .ch_stack = chan_stack, - .pvt = &pvt_spec, + .pvt = &cpu_pvt_spec, .track = cpu_track, }; /* ----------------- models ------------------ */ -static const struct model_cpu_spec cpu_spec = { - .size = sizeof(struct nosv_cpu), - .chan = &cpu_chan, - .model = &model_nosv, -}; - static const struct model_thread_spec th_spec = { .size = sizeof(struct nosv_thread), .chan = &th_chan, .model = &model_nosv, }; +static const struct model_cpu_spec cpu_spec = { + .size = sizeof(struct nosv_cpu), + .chan = &cpu_chan, + .model = &model_nosv, +}; + /* ----------------------------------------------------- */ int diff --git a/src/emu/ovni/setup.c b/src/emu/ovni/setup.c index bf78da4..36a335c 100644 --- a/src/emu/ovni/setup.c +++ b/src/emu/ovni/setup.c @@ -40,10 +40,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = { [CH_FLUSH] = &flushing_values, }; +static const long prv_flags[CH_MAX] = { + [CH_FLUSH] = PRV_SKIPDUP, +}; + static const struct model_pvt_spec pvt_spec = { .type = pvt_type, .prefix = pcf_prefix, .label = pcf_labels, + .flags = prv_flags, }; /* ----------------- tracking ------------------ */ diff --git a/src/emu/pv/prv.c b/src/emu/pv/prv.c index 7d7c34b..a5e5ad7 100644 --- a/src/emu/pv/prv.c +++ b/src/emu/pv/prv.c @@ -67,16 +67,20 @@ find_prv_chan(struct prv *prv, long id) return rchan; } -static int +static void write_line(struct prv *prv, long row_base1, long type, long value) { - int ret = fprintf(prv->file, "2:0:1:1:%ld:%ld:%ld:%ld\n", + fprintf(prv->file, "2:0:1:1:%ld:%ld:%ld:%ld\n", row_base1, prv->time, type, value); +} - if (ret < 0) - return -1; - else +static int +is_value_dup(struct prv_chan *rchan, struct value *value) +{ + if (!rchan->last_value_set) return 0; + + return value_is_equal(value, &rchan->last_value); } static int @@ -90,18 +94,25 @@ emit(struct prv *prv, struct prv_chan *rchan) return -1; } - /* Ensure we don't emit the same value twice */ - if (rchan->last_value_set && value_is_equal(&value, &rchan->last_value)) { - char buf[128]; - if (rchan->flags & PRV_DUP) { - dbg("skipping duplicated value %s for channel %s\n", - value_str(value, buf), chan->name); - return 0; - } else { + /* Only test for duplicates if not emitting them */ + if (~rchan->flags & PRV_EMITDUP) { + int is_dup = is_value_dup(rchan, &value); + if (is_dup) { + if (rchan->flags & PRV_SKIPDUP) + return 0; + + int is_null = value_is_null(value); + if (rchan->flags & PRV_SKIPNULL && is_null) + return 0; + err("error duplicated value %s for channel %s\n", value_str(value, buf), chan->name); return -1; } + + /* Only set when caring about duplicates */ + rchan->last_value = value; + rchan->last_value_set = 1; } long val = 0; @@ -111,12 +122,12 @@ emit(struct prv *prv, struct prv_chan *rchan) if (rchan->flags & PRV_NEXT) val++; - //if (val == 0) { - // err("forbidden value 0 in %s: %s\n", - // chan->name, - // value_str(value, buf)); - // return -1; - //} + if (~rchan->flags & PRV_ZERO && val == 0) { + err("forbidden value 0 in %s: %s\n", + chan->name, + value_str(value, buf)); + return -1; + } break; case VALUE_NULL: val = 0; @@ -127,16 +138,10 @@ emit(struct prv *prv, struct prv_chan *rchan) return -1; } - if (write_line(prv, rchan->row_base1, rchan->type, val) != 0) { - err("write_line failed for channel %s\n", - chan->name); - return -1; - } + write_line(prv, rchan->row_base1, rchan->type, val); dbg("written %s for chan %s", value_str(value, buf), chan->name); - rchan->last_value = value; - rchan->last_value_set = 1; return 0; } diff --git a/src/emu/pv/prv.h b/src/emu/pv/prv.h index f7da314..86af7f7 100644 --- a/src/emu/pv/prv.h +++ b/src/emu/pv/prv.h @@ -12,8 +12,11 @@ struct prv; enum prv_flags { - PRV_DUP = 1<<0, - PRV_NEXT = 1<<1, /* Add one to the channel value */ + PRV_EMITDUP = 1<<0, /* Emit duplicates (no error, emit) */ + PRV_SKIPDUP = 1<<1, /* Skip duplicates (no error, no emit) */ + PRV_SKIPNULL = 1<<2, /* Skip null duplicates (no error, no emit) */ + PRV_NEXT = 1<<3, /* Add one to the channel value */ + PRV_ZERO = 1<<4, /* Value 0 is allowed */ }; struct prv_chan { diff --git a/src/emu/thread.c b/src/emu/thread.c index 12a62e0..3b320fd 100644 --- a/src/emu/thread.c +++ b/src/emu/thread.c @@ -9,20 +9,26 @@ static const char chan_fmt[] = "thread%lu.%s"; static const char *chan_name[] = { - [TH_CHAN_CPU] = "cpu_gindex", - [TH_CHAN_TID] = "tid_active", + [TH_CHAN_CPU] = "cpu_gindex", + [TH_CHAN_TID] = "tid_active", [TH_CHAN_STATE] = "state", }; static const int chan_type[] = { - [TH_CHAN_TID] = 2, + [TH_CHAN_CPU] = 6, + [TH_CHAN_TID] = 2, [TH_CHAN_STATE] = 4, - [TH_CHAN_CPU] = 6, +}; + +static const long prv_flags[] = { + [TH_CHAN_CPU] = PRV_SKIPDUP | PRV_NEXT, /* Add one to the cpu gindex */ + [TH_CHAN_TID] = PRV_SKIPDUP, + [TH_CHAN_STATE] = PRV_SKIPDUP, }; static const char *pvt_name[] = { - [TH_CHAN_CPU] = "Thread: CPU affinity", - [TH_CHAN_TID] = "Thread: TID of the ACTIVE thread", + [TH_CHAN_CPU] = "Thread: CPU affinity", + [TH_CHAN_TID] = "Thread: TID of the ACTIVE thread", [TH_CHAN_STATE] = "Thread: thread state", }; @@ -201,11 +207,7 @@ thread_connect(struct thread *th, struct bay *bay, struct recorder *rec) long type = chan_type[i]; long row = th->gindex; - long flags = PRV_DUP; - - /* Add one to the cpu gindex in the PRV output */ - if (i == TH_CHAN_CPU) - flags |= PRV_NEXT; + long flags = prv_flags[i]; if (prv_register(prv, row, type, bay, c, flags)) { err("prv_register failed");