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:
parent
48cd4de92e
commit
a24477629d
@ -26,6 +26,12 @@ static int chan_type[] = {
|
|||||||
[CPU_CHAN_THACT] = -1,
|
[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
|
void
|
||||||
cpu_init_begin(struct cpu *cpu, int index, int phyid, int is_virtual)
|
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;
|
continue;
|
||||||
|
|
||||||
long row = cpu->gindex;
|
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");
|
err("prv_register failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -41,10 +41,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = {
|
|||||||
[CH_CS] = &kernel_cs_values,
|
[CH_CS] = &kernel_cs_values,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const long prv_flags[CH_MAX] = {
|
||||||
|
[CH_CS] = PRV_SKIPDUP,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct model_pvt_spec pvt_spec = {
|
static const struct model_pvt_spec pvt_spec = {
|
||||||
.type = pvt_type,
|
.type = pvt_type,
|
||||||
.prefix = pcf_prefix,
|
.prefix = pcf_prefix,
|
||||||
.label = pcf_labels,
|
.label = pcf_labels,
|
||||||
|
.flags = prv_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- tracking ------------------ */
|
/* ----------------- tracking ------------------ */
|
||||||
|
@ -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);
|
struct model_cpu *cpu = EXT(scpu, id);
|
||||||
const struct model_chan_spec *spec = cpu->spec->chan;
|
const struct model_chan_spec *spec = cpu->spec->chan;
|
||||||
|
const long *flags_arr = spec->pvt->flags;
|
||||||
for (int i = 0; i < spec->nch; i++) {
|
for (int i = 0; i < spec->nch; i++) {
|
||||||
struct chan *out = track_get_output(&cpu->track[i]);
|
struct chan *out = track_get_output(&cpu->track[i]);
|
||||||
long type = spec->pvt->type[i];
|
long type = spec->pvt->type[i];
|
||||||
long row = scpu->gindex;
|
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");
|
err("prv_register failed");
|
||||||
return -1;
|
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);
|
struct model_thread *th = EXT(sth, id);
|
||||||
const struct model_chan_spec *spec = th->spec->chan;
|
const struct model_chan_spec *spec = th->spec->chan;
|
||||||
|
const long *flags_arr = spec->pvt->flags;
|
||||||
for (int i = 0; i < spec->nch; i++) {
|
for (int i = 0; i < spec->nch; i++) {
|
||||||
struct chan *out = track_get_output(&th->track[i]);
|
struct chan *out = track_get_output(&th->track[i]);
|
||||||
long type = spec->pvt->type[i];
|
long type = spec->pvt->type[i];
|
||||||
long row = sth->gindex;
|
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");
|
err("prv_register failed");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ struct model_pvt_spec {
|
|||||||
const int *type;
|
const int *type;
|
||||||
const char **prefix;
|
const char **prefix;
|
||||||
const char **suffix;
|
const char **suffix;
|
||||||
|
const long *flags;
|
||||||
const struct pcf_value_label (**label)[];
|
const struct pcf_value_label (**label)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -92,10 +92,19 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = {
|
|||||||
[CH_THREAD] = &nanos6_thread_type,
|
[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 = {
|
static const struct model_pvt_spec pvt_spec = {
|
||||||
.type = pvt_type,
|
.type = pvt_type,
|
||||||
.prefix = pcf_prefix,
|
.prefix = pcf_prefix,
|
||||||
.label = pcf_labels,
|
.label = pcf_labels,
|
||||||
|
.flags = prv_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- tracking ------------------ */
|
/* ----------------- tracking ------------------ */
|
||||||
|
@ -49,10 +49,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = {
|
|||||||
[CH_SUBSYSTEM] = &nodes_ss_values,
|
[CH_SUBSYSTEM] = &nodes_ss_values,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const long prv_flags[CH_MAX] = {
|
||||||
|
[CH_SUBSYSTEM] = PRV_SKIPDUP,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct model_pvt_spec pvt_spec = {
|
static const struct model_pvt_spec pvt_spec = {
|
||||||
.type = pvt_type,
|
.type = pvt_type,
|
||||||
.prefix = pcf_prefix,
|
.prefix = pcf_prefix,
|
||||||
.label = pcf_labels,
|
.label = pcf_labels,
|
||||||
|
.flags = prv_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- tracking ------------------ */
|
/* ----------------- tracking ------------------ */
|
||||||
|
@ -75,10 +75,37 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = {
|
|||||||
[CH_SUBSYSTEM] = &nosv_ss_values,
|
[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,
|
.type = pvt_type,
|
||||||
.prefix = pcf_prefix,
|
.prefix = pcf_prefix,
|
||||||
.label = pcf_labels,
|
.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 ------------------ */
|
/* ----------------- tracking ------------------ */
|
||||||
@ -107,7 +134,7 @@ static const struct model_chan_spec th_chan = {
|
|||||||
.ch_names = chan_name,
|
.ch_names = chan_name,
|
||||||
.ch_stack = chan_stack,
|
.ch_stack = chan_stack,
|
||||||
.ch_dup = chan_dup,
|
.ch_dup = chan_dup,
|
||||||
.pvt = &pvt_spec,
|
.pvt = &th_pvt_spec,
|
||||||
.track = th_track,
|
.track = th_track,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -116,24 +143,24 @@ static const struct model_chan_spec cpu_chan = {
|
|||||||
.prefix = model_name,
|
.prefix = model_name,
|
||||||
.ch_names = chan_name,
|
.ch_names = chan_name,
|
||||||
.ch_stack = chan_stack,
|
.ch_stack = chan_stack,
|
||||||
.pvt = &pvt_spec,
|
.pvt = &cpu_pvt_spec,
|
||||||
.track = cpu_track,
|
.track = cpu_track,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- models ------------------ */
|
/* ----------------- 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 = {
|
static const struct model_thread_spec th_spec = {
|
||||||
.size = sizeof(struct nosv_thread),
|
.size = sizeof(struct nosv_thread),
|
||||||
.chan = &th_chan,
|
.chan = &th_chan,
|
||||||
.model = &model_nosv,
|
.model = &model_nosv,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct model_cpu_spec cpu_spec = {
|
||||||
|
.size = sizeof(struct nosv_cpu),
|
||||||
|
.chan = &cpu_chan,
|
||||||
|
.model = &model_nosv,
|
||||||
|
};
|
||||||
|
|
||||||
/* ----------------------------------------------------- */
|
/* ----------------------------------------------------- */
|
||||||
|
|
||||||
int
|
int
|
||||||
|
@ -40,10 +40,15 @@ static const struct pcf_value_label (*pcf_labels[CH_MAX])[] = {
|
|||||||
[CH_FLUSH] = &flushing_values,
|
[CH_FLUSH] = &flushing_values,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const long prv_flags[CH_MAX] = {
|
||||||
|
[CH_FLUSH] = PRV_SKIPDUP,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct model_pvt_spec pvt_spec = {
|
static const struct model_pvt_spec pvt_spec = {
|
||||||
.type = pvt_type,
|
.type = pvt_type,
|
||||||
.prefix = pcf_prefix,
|
.prefix = pcf_prefix,
|
||||||
.label = pcf_labels,
|
.label = pcf_labels,
|
||||||
|
.flags = prv_flags,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* ----------------- tracking ------------------ */
|
/* ----------------- tracking ------------------ */
|
||||||
|
@ -67,16 +67,20 @@ find_prv_chan(struct prv *prv, long id)
|
|||||||
return rchan;
|
return rchan;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
write_line(struct prv *prv, long row_base1, long type, long value)
|
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);
|
row_base1, prv->time, type, value);
|
||||||
|
}
|
||||||
|
|
||||||
if (ret < 0)
|
static int
|
||||||
return -1;
|
is_value_dup(struct prv_chan *rchan, struct value *value)
|
||||||
else
|
{
|
||||||
|
if (!rchan->last_value_set)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
return value_is_equal(value, &rchan->last_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -90,18 +94,25 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Ensure we don't emit the same value twice */
|
/* Only test for duplicates if not emitting them */
|
||||||
if (rchan->last_value_set && value_is_equal(&value, &rchan->last_value)) {
|
if (~rchan->flags & PRV_EMITDUP) {
|
||||||
char buf[128];
|
int is_dup = is_value_dup(rchan, &value);
|
||||||
if (rchan->flags & PRV_DUP) {
|
if (is_dup) {
|
||||||
dbg("skipping duplicated value %s for channel %s\n",
|
if (rchan->flags & PRV_SKIPDUP)
|
||||||
value_str(value, buf), chan->name);
|
return 0;
|
||||||
return 0;
|
|
||||||
} else {
|
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",
|
err("error duplicated value %s for channel %s\n",
|
||||||
value_str(value, buf), chan->name);
|
value_str(value, buf), chan->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Only set when caring about duplicates */
|
||||||
|
rchan->last_value = value;
|
||||||
|
rchan->last_value_set = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
long val = 0;
|
long val = 0;
|
||||||
@ -111,12 +122,12 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
if (rchan->flags & PRV_NEXT)
|
if (rchan->flags & PRV_NEXT)
|
||||||
val++;
|
val++;
|
||||||
|
|
||||||
//if (val == 0) {
|
if (~rchan->flags & PRV_ZERO && val == 0) {
|
||||||
// err("forbidden value 0 in %s: %s\n",
|
err("forbidden value 0 in %s: %s\n",
|
||||||
// chan->name,
|
chan->name,
|
||||||
// value_str(value, buf));
|
value_str(value, buf));
|
||||||
// return -1;
|
return -1;
|
||||||
//}
|
}
|
||||||
break;
|
break;
|
||||||
case VALUE_NULL:
|
case VALUE_NULL:
|
||||||
val = 0;
|
val = 0;
|
||||||
@ -127,16 +138,10 @@ emit(struct prv *prv, struct prv_chan *rchan)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (write_line(prv, rchan->row_base1, rchan->type, val) != 0) {
|
write_line(prv, rchan->row_base1, rchan->type, val);
|
||||||
err("write_line failed for channel %s\n",
|
|
||||||
chan->name);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dbg("written %s for chan %s", value_str(value, buf), chan->name);
|
dbg("written %s for chan %s", value_str(value, buf), chan->name);
|
||||||
|
|
||||||
rchan->last_value = value;
|
|
||||||
rchan->last_value_set = 1;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -12,8 +12,11 @@
|
|||||||
struct prv;
|
struct prv;
|
||||||
|
|
||||||
enum prv_flags {
|
enum prv_flags {
|
||||||
PRV_DUP = 1<<0,
|
PRV_EMITDUP = 1<<0, /* Emit duplicates (no error, emit) */
|
||||||
PRV_NEXT = 1<<1, /* Add one to the channel value */
|
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 {
|
struct prv_chan {
|
||||||
|
@ -9,20 +9,26 @@
|
|||||||
|
|
||||||
static const char chan_fmt[] = "thread%lu.%s";
|
static const char chan_fmt[] = "thread%lu.%s";
|
||||||
static const char *chan_name[] = {
|
static const char *chan_name[] = {
|
||||||
[TH_CHAN_CPU] = "cpu_gindex",
|
[TH_CHAN_CPU] = "cpu_gindex",
|
||||||
[TH_CHAN_TID] = "tid_active",
|
[TH_CHAN_TID] = "tid_active",
|
||||||
[TH_CHAN_STATE] = "state",
|
[TH_CHAN_STATE] = "state",
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int chan_type[] = {
|
static const int chan_type[] = {
|
||||||
[TH_CHAN_TID] = 2,
|
[TH_CHAN_CPU] = 6,
|
||||||
|
[TH_CHAN_TID] = 2,
|
||||||
[TH_CHAN_STATE] = 4,
|
[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[] = {
|
static const char *pvt_name[] = {
|
||||||
[TH_CHAN_CPU] = "Thread: CPU affinity",
|
[TH_CHAN_CPU] = "Thread: CPU affinity",
|
||||||
[TH_CHAN_TID] = "Thread: TID of the ACTIVE thread",
|
[TH_CHAN_TID] = "Thread: TID of the ACTIVE thread",
|
||||||
[TH_CHAN_STATE] = "Thread: thread state",
|
[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 type = chan_type[i];
|
||||||
long row = th->gindex;
|
long row = th->gindex;
|
||||||
long flags = PRV_DUP;
|
long flags = prv_flags[i];
|
||||||
|
|
||||||
/* Add one to the cpu gindex in the PRV output */
|
|
||||||
if (i == TH_CHAN_CPU)
|
|
||||||
flags |= PRV_NEXT;
|
|
||||||
|
|
||||||
if (prv_register(prv, row, type, bay, c, flags)) {
|
if (prv_register(prv, row, type, bay, c, flags)) {
|
||||||
err("prv_register failed");
|
err("prv_register failed");
|
||||||
|
Loading…
Reference in New Issue
Block a user