Early duplicate state detection in channels
These checks allows the emulator to abort at the moment in which two consecutive states are going to be emitted by the channel, showing the culpirit in the backtrace. Waiting for the check in chan_emit() hides the source of the problem.
This commit is contained in:
parent
9944b391ae
commit
cddda71cfb
64
chan.c
64
chan.c
@ -172,6 +172,25 @@ chan_set(struct ovni_chan *chan, int st)
|
|||||||
|
|
||||||
assert(chan->enabled);
|
assert(chan->enabled);
|
||||||
|
|
||||||
|
/* Only chan_set can set the 0 state */
|
||||||
|
if(st < 0)
|
||||||
|
{
|
||||||
|
err("chan_set: cannot set a negative state %d\n", st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Don't enforce this check if we are dirty because the channel was
|
||||||
|
* just enabled; it may collide with a new state 0 set via chan_set()
|
||||||
|
* used by the tracking channels */
|
||||||
|
if(chan->dirty != CHAN_DIRTY_ACTIVE
|
||||||
|
&& chan->lastst >= 0
|
||||||
|
&& chan->lastst == st)
|
||||||
|
{
|
||||||
|
err("chan_set id=%d cannot emit the state %d twice\n",
|
||||||
|
chan->id, st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if(chan->n == 0)
|
if(chan->n == 0)
|
||||||
chan->n = 1;
|
chan->n = 1;
|
||||||
|
|
||||||
@ -205,9 +224,22 @@ chan_push(struct ovni_chan *chan, int st)
|
|||||||
|
|
||||||
assert(chan->enabled);
|
assert(chan->enabled);
|
||||||
|
|
||||||
|
if(st <= 0)
|
||||||
|
{
|
||||||
|
err("chan_push: cannot push a non-positive state %d\n", st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
/* Cannot be dirty */
|
/* Cannot be dirty */
|
||||||
assert(chan->dirty == 0);
|
assert(chan->dirty == 0);
|
||||||
|
|
||||||
|
if(chan->lastst >= 0 && chan->lastst == st)
|
||||||
|
{
|
||||||
|
err("chan_push id=%d cannot emit the state %d twice\n",
|
||||||
|
chan->id, st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
if(chan->n >= MAX_CHAN_STACK)
|
if(chan->n >= MAX_CHAN_STACK)
|
||||||
{
|
{
|
||||||
err("channel stack full\n");
|
err("channel stack full\n");
|
||||||
@ -248,6 +280,24 @@ chan_pop(struct ovni_chan *chan, int expected_st)
|
|||||||
}
|
}
|
||||||
|
|
||||||
chan->n--;
|
chan->n--;
|
||||||
|
|
||||||
|
/* Take the current stack value */
|
||||||
|
st = chan_get_st(chan);
|
||||||
|
|
||||||
|
/* A st == 0 can be obtained when returning to the initial state */
|
||||||
|
if(st < 0)
|
||||||
|
{
|
||||||
|
err("chan_pop: obtained negative state %d from the stack\n", st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(chan->lastst >= 0 && chan->lastst == st)
|
||||||
|
{
|
||||||
|
err("chan_pop id=%d cannot emit the state %d twice\n",
|
||||||
|
chan->id, st);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
chan->t = *chan->clock;
|
chan->t = *chan->clock;
|
||||||
|
|
||||||
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
||||||
@ -264,7 +314,19 @@ chan_ev(struct ovni_chan *chan, int ev)
|
|||||||
|
|
||||||
/* Cannot be dirty */
|
/* Cannot be dirty */
|
||||||
assert(chan->dirty == 0);
|
assert(chan->dirty == 0);
|
||||||
assert(ev >= 0);
|
|
||||||
|
if(ev <= 0)
|
||||||
|
{
|
||||||
|
err("chan_ev: cannot emit non-positive state %d\n", ev);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(chan->lastst >= 0 && chan->lastst == ev)
|
||||||
|
{
|
||||||
|
err("chan_ev id=%d cannot emit the state %d twice\n",
|
||||||
|
chan->id, ev);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
chan->ev = ev;
|
chan->ev = ev;
|
||||||
chan->t = *chan->clock;
|
chan->t = *chan->clock;
|
||||||
|
Loading…
Reference in New Issue
Block a user