Set PRV flags explicitly per channel

Added PRV_EMITDUP and PRV_SKIPDUP to allow the check to be skipped. By
default it will fail to emit duplicated values.
This commit is contained in:
Rodrigo Arias 2023-02-23 19:26:37 +01:00 committed by Rodrigo Arias Mallo
parent 48cd4de92e
commit a24477629d
11 changed files with 124 additions and 51 deletions

View File

@ -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;
}

View File

@ -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 ------------------ */

View File

@ -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;
}

View File

@ -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)[];
};

View File

@ -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 ------------------ */

View File

@ -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 ------------------ */

View File

@ -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

View File

@ -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 ------------------ */

View File

@ -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;
}

View File

@ -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 {

View File

@ -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");