Only allow and emit state transitions
Fixes the ghost events shown in the PRV trace. Only transitions to a different state are allowed now.
This commit is contained in:
parent
78f5db4bce
commit
557371e836
54
chan.c
54
chan.c
@ -37,15 +37,17 @@ chan_init(struct ovni_chan *chan, enum chan_track track, int row, int type, FILE
|
|||||||
chan->row = row;
|
chan->row = row;
|
||||||
chan->dirty = 0;
|
chan->dirty = 0;
|
||||||
chan->track = track;
|
chan->track = track;
|
||||||
|
chan->lastst = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
mark_dirty(struct ovni_chan *chan)
|
mark_dirty(struct ovni_chan *chan, enum chan_dirty dirty)
|
||||||
{
|
{
|
||||||
assert(chan->dirty == 0);
|
assert(chan->dirty == CHAN_CLEAN);
|
||||||
|
assert(dirty != CHAN_CLEAN);
|
||||||
|
|
||||||
dbg("adding dirty chan %d to list\n", chan->id);
|
dbg("adding dirty chan %d to list\n", chan->id);
|
||||||
chan->dirty = 1;
|
chan->dirty = dirty;
|
||||||
DL_APPEND(*chan->update_list, chan);
|
DL_APPEND(*chan->update_list, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -75,7 +77,7 @@ chan_th_init(struct ovni_ethread *th,
|
|||||||
chan->enabled = enabled;
|
chan->enabled = enabled;
|
||||||
chan->stack[chan->n++] = init_st;
|
chan->stack[chan->n++] = init_st;
|
||||||
if(dirty)
|
if(dirty)
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -104,7 +106,7 @@ chan_cpu_init(struct ovni_cpu *cpu,
|
|||||||
chan->enabled = enabled;
|
chan->enabled = enabled;
|
||||||
chan->stack[chan->n++] = init_st;
|
chan->stack[chan->n++] = init_st;
|
||||||
if(dirty)
|
if(dirty)
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -139,7 +141,7 @@ chan_enable(struct ovni_chan *chan, int enabled)
|
|||||||
/* Only append if not dirty */
|
/* Only append if not dirty */
|
||||||
if(!chan->dirty)
|
if(!chan->dirty)
|
||||||
{
|
{
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -179,7 +181,7 @@ chan_set(struct ovni_chan *chan, int st)
|
|||||||
/* Only append if not dirty */
|
/* Only append if not dirty */
|
||||||
if(!chan->dirty)
|
if(!chan->dirty)
|
||||||
{
|
{
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -215,7 +217,7 @@ chan_push(struct ovni_chan *chan, int st)
|
|||||||
chan->stack[chan->n++] = st;
|
chan->stack[chan->n++] = st;
|
||||||
chan->t = *chan->clock;
|
chan->t = *chan->clock;
|
||||||
|
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -248,7 +250,7 @@ chan_pop(struct ovni_chan *chan, int expected_st)
|
|||||||
chan->n--;
|
chan->n--;
|
||||||
chan->t = *chan->clock;
|
chan->t = *chan->clock;
|
||||||
|
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
||||||
|
|
||||||
return st;
|
return st;
|
||||||
}
|
}
|
||||||
@ -267,7 +269,7 @@ chan_ev(struct ovni_chan *chan, int ev)
|
|||||||
chan->ev = ev;
|
chan->ev = ev;
|
||||||
chan->t = *chan->clock;
|
chan->t = *chan->clock;
|
||||||
|
|
||||||
mark_dirty(chan);
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -283,6 +285,32 @@ chan_get_st(struct ovni_chan *chan)
|
|||||||
return chan->stack[chan->n-1];
|
return chan->stack[chan->n-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
emit(struct ovni_chan *chan, int64_t t, int state)
|
||||||
|
{
|
||||||
|
assert(chan->dirty != CHAN_CLEAN);
|
||||||
|
|
||||||
|
/* A channel can only emit the same state as lastst if is dirty because
|
||||||
|
* it has been enabled or disabled. Otherwise is a bug (ie. you have two
|
||||||
|
* consecutive ovni events?) */
|
||||||
|
if(chan->lastst != -1
|
||||||
|
&& chan->dirty == CHAN_DIRTY_VALUE
|
||||||
|
&& chan->lastst == state)
|
||||||
|
{
|
||||||
|
/* TODO: Print the raw clock of the offending event */
|
||||||
|
err("chan: id=%d cannot emit the same state %d twice\n",
|
||||||
|
chan->id, state);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(chan->lastst != state)
|
||||||
|
{
|
||||||
|
prv_ev(chan->prv, chan->row, t, chan->type, state);
|
||||||
|
|
||||||
|
chan->lastst = state;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
emit_ev(struct ovni_chan *chan)
|
emit_ev(struct ovni_chan *chan)
|
||||||
{
|
{
|
||||||
@ -294,8 +322,8 @@ emit_ev(struct ovni_chan *chan)
|
|||||||
new = chan->ev;
|
new = chan->ev;
|
||||||
last = chan_get_st(chan);
|
last = chan_get_st(chan);
|
||||||
|
|
||||||
prv_ev(chan->prv, chan->row, chan->t-1, chan->type, new);
|
emit(chan, chan->t-1, new);
|
||||||
prv_ev(chan->prv, chan->row, chan->t, chan->type, last);
|
emit(chan, chan->t, last);
|
||||||
|
|
||||||
chan->ev = -1;
|
chan->ev = -1;
|
||||||
}
|
}
|
||||||
@ -307,7 +335,7 @@ emit_st(struct ovni_chan *chan)
|
|||||||
|
|
||||||
st = chan_get_st(chan);
|
st = chan_get_st(chan);
|
||||||
|
|
||||||
prv_ev(chan->prv, chan->row, chan->t, chan->type, st);
|
emit(chan, chan->t, st);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Emits either the current state or punctual event in the PRV file */
|
/* Emits either the current state or punctual event in the PRV file */
|
||||||
|
7
emu.c
7
emu.c
@ -82,7 +82,7 @@ print_cur_ev(struct ovni_emu *emu)
|
|||||||
static void
|
static void
|
||||||
cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
|
cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
|
||||||
{
|
{
|
||||||
int th_enabled, cpu_enabled;
|
int th_enabled, cpu_enabled, st;
|
||||||
struct ovni_chan *th_chan;
|
struct ovni_chan *th_chan;
|
||||||
|
|
||||||
assert(th);
|
assert(th);
|
||||||
@ -112,7 +112,9 @@ cpu_update_tracking_chan(struct ovni_chan *cpu_chan, struct ovni_ethread *th)
|
|||||||
if(th_enabled && cpu_enabled)
|
if(th_enabled && cpu_enabled)
|
||||||
{
|
{
|
||||||
/* Both enabled: simply follow the same value */
|
/* Both enabled: simply follow the same value */
|
||||||
chan_set(cpu_chan, chan_get_st(th_chan));
|
st = chan_get_st(th_chan);
|
||||||
|
if(chan_get_st(cpu_chan) != st)
|
||||||
|
chan_set(cpu_chan, st);
|
||||||
}
|
}
|
||||||
else if(th_enabled && !cpu_enabled)
|
else if(th_enabled && !cpu_enabled)
|
||||||
{
|
{
|
||||||
@ -192,6 +194,7 @@ emu_cpu_update_chan(struct ovni_cpu *cpu, struct ovni_chan *cpu_chan)
|
|||||||
if(!chan_is_enabled(cpu_chan))
|
if(!chan_is_enabled(cpu_chan))
|
||||||
chan_enable(cpu_chan, 1);
|
chan_enable(cpu_chan, 1);
|
||||||
|
|
||||||
|
if(chan_get_st(cpu_chan) != ST_TOO_MANY_TH)
|
||||||
chan_set(cpu_chan, ST_TOO_MANY_TH);
|
chan_set(cpu_chan, ST_TOO_MANY_TH);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
17
emu.h
17
emu.h
@ -170,6 +170,16 @@ enum chan_to_prv_type {
|
|||||||
CHAN_CPU = 2,
|
CHAN_CPU = 2,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum chan_dirty {
|
||||||
|
CHAN_CLEAN = 0,
|
||||||
|
|
||||||
|
/* The channel is dirty because it has been enabled or disabled */
|
||||||
|
CHAN_DIRTY_ACTIVE = 1,
|
||||||
|
|
||||||
|
/* The channel is dirty because it changed the state */
|
||||||
|
CHAN_DIRTY_VALUE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
/* Same order as `enum chan` */
|
/* Same order as `enum chan` */
|
||||||
static const int chan_to_prvtype[CHAN_MAX][3] = {
|
static const int chan_to_prvtype[CHAN_MAX][3] = {
|
||||||
/* Channel TH CPU */
|
/* Channel TH CPU */
|
||||||
@ -212,6 +222,9 @@ struct ovni_chan {
|
|||||||
/* What state should be shown in errors */
|
/* What state should be shown in errors */
|
||||||
int badst;
|
int badst;
|
||||||
|
|
||||||
|
/* Last state emitted (-1 otherwise) */
|
||||||
|
int lastst;
|
||||||
|
|
||||||
/* Punctual event: -1 if not used */
|
/* Punctual event: -1 if not used */
|
||||||
int ev;
|
int ev;
|
||||||
|
|
||||||
@ -227,8 +240,8 @@ struct ovni_chan {
|
|||||||
/* Paraver row */
|
/* Paraver row */
|
||||||
int row;
|
int row;
|
||||||
|
|
||||||
/* 1 if channel needs flush to PRV */
|
/* Type of dirty */
|
||||||
int dirty;
|
enum chan_dirty dirty;
|
||||||
|
|
||||||
/* Where should the events be written to? */
|
/* Where should the events be written to? */
|
||||||
FILE *prv;
|
FILE *prv;
|
||||||
|
Loading…
Reference in New Issue
Block a user