2022-09-19 12:39:02 +02:00
|
|
|
/* Copyright (c) 2021 Barcelona Supercomputing Center (BSC)
|
|
|
|
* SPDX-License-Identifier: GPL-3.0-or-later */
|
2021-10-26 18:42:41 +02:00
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
#include "chan.h"
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
#include "emu.h"
|
|
|
|
#include "prv.h"
|
2021-10-18 12:47:51 +02:00
|
|
|
#include "utlist.h"
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
static void
|
2021-11-08 17:05:22 +01:00
|
|
|
chan_init(struct ovni_chan *chan, enum chan_track track, int row, int type, FILE *prv, int64_t *clock)
|
2021-10-21 16:15:29 +02:00
|
|
|
{
|
|
|
|
chan->n = 0;
|
|
|
|
chan->type = type;
|
|
|
|
chan->enabled = 0;
|
|
|
|
chan->badst = ST_NULL;
|
|
|
|
chan->ev = -1;
|
|
|
|
chan->prv = prv;
|
|
|
|
chan->clock = clock;
|
2021-10-21 16:41:52 +02:00
|
|
|
chan->t = *clock;
|
2021-10-21 16:15:29 +02:00
|
|
|
chan->row = row;
|
|
|
|
chan->dirty = 0;
|
2021-10-21 16:41:52 +02:00
|
|
|
chan->track = track;
|
2021-11-17 12:08:25 +01:00
|
|
|
chan->lastst = -1;
|
2021-10-21 16:41:52 +02:00
|
|
|
}
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
static void
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(struct ovni_chan *chan, enum chan_dirty dirty)
|
2021-10-18 12:47:51 +02:00
|
|
|
{
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty != CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("mark_dirty: chan %d already dirty\n", chan->id);
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (dirty == CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("mark_dirty: cannot use CHAN_CLEAN\n");
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
dbg("adding dirty chan %d to list\n", chan->id);
|
2021-11-17 12:08:25 +01:00
|
|
|
chan->dirty = dirty;
|
2021-10-18 12:47:51 +02:00
|
|
|
DL_APPEND(*chan->update_list, chan);
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:41:52 +02:00
|
|
|
void
|
2021-10-18 12:47:51 +02:00
|
|
|
chan_th_init(struct ovni_ethread *th,
|
2022-09-29 15:34:44 +02:00
|
|
|
struct ovni_chan **update_list,
|
|
|
|
enum chan id,
|
|
|
|
enum chan_track track,
|
|
|
|
int init_st,
|
|
|
|
int enabled,
|
|
|
|
int dirty,
|
|
|
|
int row,
|
|
|
|
FILE *prv,
|
|
|
|
int64_t *clock)
|
2021-10-21 16:41:52 +02:00
|
|
|
{
|
|
|
|
struct ovni_chan *chan;
|
|
|
|
int prvth;
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
chan = &th->chan[id];
|
2022-07-01 17:54:18 +02:00
|
|
|
prvth = chan_to_prvtype[id];
|
2021-10-21 16:41:52 +02:00
|
|
|
|
|
|
|
chan_init(chan, track, row, prvth, prv, clock);
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
chan->id = id;
|
|
|
|
chan->thread = th;
|
|
|
|
chan->update_list = update_list;
|
|
|
|
chan->enabled = enabled;
|
|
|
|
chan->stack[chan->n++] = init_st;
|
2022-09-29 15:34:44 +02:00
|
|
|
if (dirty)
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
2021-10-21 16:41:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2021-10-18 12:47:51 +02:00
|
|
|
chan_cpu_init(struct ovni_cpu *cpu,
|
2022-09-29 15:34:44 +02:00
|
|
|
struct ovni_chan **update_list,
|
|
|
|
enum chan id,
|
|
|
|
enum chan_track track,
|
|
|
|
int init_st,
|
|
|
|
int enabled,
|
|
|
|
int dirty,
|
|
|
|
int row,
|
|
|
|
FILE *prv,
|
|
|
|
int64_t *clock)
|
2021-10-21 16:41:52 +02:00
|
|
|
{
|
|
|
|
struct ovni_chan *chan;
|
|
|
|
int prvcpu;
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
chan = &cpu->chan[id];
|
2022-07-01 17:54:18 +02:00
|
|
|
prvcpu = chan_to_prvtype[id];
|
2021-10-21 15:46:32 +02:00
|
|
|
|
|
|
|
chan_init(chan, track, row, prvcpu, prv, clock);
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
chan->id = id;
|
|
|
|
chan->cpu = cpu;
|
|
|
|
chan->update_list = update_list;
|
2021-10-21 15:46:32 +02:00
|
|
|
chan->enabled = enabled;
|
|
|
|
chan->stack[chan->n++] = init_st;
|
2022-09-29 15:34:44 +02:00
|
|
|
if (dirty)
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
static void
|
|
|
|
chan_dump_update_list(struct ovni_chan *chan)
|
|
|
|
{
|
|
|
|
struct ovni_chan *c;
|
|
|
|
|
|
|
|
dbg("update list for chan %d at %p:\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, (void *) chan);
|
|
|
|
for (c = *chan->update_list; c; c = c->next) {
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg(" chan %d at %p\n", c->id, (void *) c);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
void
|
|
|
|
chan_enable(struct ovni_chan *chan, int enabled)
|
|
|
|
{
|
2021-10-21 16:41:52 +02:00
|
|
|
/* Can be dirty */
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("chan_enable chan=%d enabled=%d\n", chan->id, enabled);
|
2021-10-21 16:41:52 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->enabled == enabled) {
|
2021-11-19 16:47:35 +01:00
|
|
|
err("chan_enable: chan already in enabled=%d\n", enabled);
|
2021-10-21 16:41:52 +02:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
chan->enabled = enabled;
|
2021-10-21 16:41:52 +02:00
|
|
|
chan->t = *chan->clock;
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
/* Only append if not dirty */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->dirty) {
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_ACTIVE);
|
2022-09-29 15:34:44 +02:00
|
|
|
} else {
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("already dirty chan %d: skip update list\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id);
|
2021-10-18 12:47:51 +02:00
|
|
|
chan_dump_update_list(chan);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
chan_disable(struct ovni_chan *chan)
|
|
|
|
{
|
|
|
|
chan_enable(chan, 0);
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
chan_is_enabled(struct ovni_chan *chan)
|
|
|
|
{
|
|
|
|
return chan->enabled;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
chan_set(struct ovni_chan *chan, int st)
|
|
|
|
{
|
2021-10-18 12:47:51 +02:00
|
|
|
/* Can be dirty */
|
|
|
|
|
|
|
|
dbg("chan_set chan %d st=%d\n", chan->id, st);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->enabled)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_set: chan %d not enabled\n", chan->id);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2021-11-19 16:22:37 +01:00
|
|
|
/* Only chan_set can set the 0 state */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (st < 0)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_set: cannot set a negative state %d\n", st);
|
2021-11-19 16:22:37 +01:00
|
|
|
|
|
|
|
/* 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 */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty != CHAN_DIRTY_ACTIVE
|
|
|
|
&& chan->lastst >= 0
|
|
|
|
&& chan->lastst == st) {
|
2021-11-19 16:22:37 +01:00
|
|
|
err("chan_set id=%d cannot emit the state %d twice\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, st);
|
2021-11-19 16:22:37 +01:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->n == 0)
|
2021-10-21 16:15:29 +02:00
|
|
|
chan->n = 1;
|
|
|
|
|
2021-10-21 16:41:52 +02:00
|
|
|
chan->stack[chan->n - 1] = st;
|
2021-10-21 16:15:29 +02:00
|
|
|
chan->t = *chan->clock;
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
/* Only append if not dirty */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->dirty) {
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
2022-09-29 15:34:44 +02:00
|
|
|
} else {
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("already dirty chan %d: skip update list\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id);
|
2021-10-18 12:47:51 +02:00
|
|
|
chan_dump_update_list(chan);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
void
|
|
|
|
chan_push(struct ovni_chan *chan, int st)
|
|
|
|
{
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("chan_push chan %d st=%d\n", chan->id, st);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->enabled)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_push: chan %d not enabled\n", chan->id);
|
2021-10-18 12:47:51 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (st <= 0) {
|
2021-11-19 16:22:37 +01:00
|
|
|
err("chan_push: cannot push a non-positive state %d\n", st);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
/* Cannot be dirty */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty != CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_push: chan %d not clean", chan->id);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->lastst >= 0 && chan->lastst == st) {
|
2021-11-19 16:22:37 +01:00
|
|
|
err("chan_push id=%d cannot emit the state %d twice\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, st);
|
2021-11-19 16:22:37 +01:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->n >= MAX_CHAN_STACK) {
|
2021-11-19 16:47:35 +01:00
|
|
|
err("chan_push: channel stack full\n");
|
|
|
|
abort();
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
chan->stack[chan->n++] = st;
|
|
|
|
chan->t = *chan->clock;
|
2021-10-18 12:47:51 +02:00
|
|
|
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
chan_pop(struct ovni_chan *chan, int expected_st)
|
|
|
|
{
|
|
|
|
int st;
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("chan_pop chan %d expected_st=%d\n", chan->id, expected_st);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->enabled)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_pop: chan %d not enabled\n", chan->id);
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
/* Cannot be dirty */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty != CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_pop: chan %d not clean", chan->id);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->n <= 0) {
|
2021-11-19 16:47:35 +01:00
|
|
|
err("chan_pop: channel empty\n");
|
|
|
|
abort();
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
st = chan->stack[chan->n - 1];
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (expected_st >= 0 && st != expected_st) {
|
2021-11-19 16:47:35 +01:00
|
|
|
err("chan_pop: unexpected channel state %d (expected %d)\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
st, expected_st);
|
2021-11-19 16:47:35 +01:00
|
|
|
abort();
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
chan->n--;
|
2021-11-19 16:22:37 +01:00
|
|
|
|
|
|
|
/* Take the current stack value */
|
|
|
|
st = chan_get_st(chan);
|
|
|
|
|
|
|
|
/* A st == 0 can be obtained when returning to the initial state */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (st < 0) {
|
2021-11-19 16:22:37 +01:00
|
|
|
err("chan_pop: obtained negative state %d from the stack\n", st);
|
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->lastst >= 0 && chan->lastst == st) {
|
2021-11-19 16:22:37 +01:00
|
|
|
err("chan_pop id=%d cannot emit the state %d twice\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, st);
|
2021-11-19 16:22:37 +01:00
|
|
|
abort();
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
chan->t = *chan->clock;
|
2021-10-18 12:47:51 +02:00
|
|
|
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
|
|
|
return st;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
chan_ev(struct ovni_chan *chan, int ev)
|
|
|
|
{
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("chan_ev chan %d ev=%d\n", chan->id, ev);
|
2021-10-21 16:41:52 +02:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->enabled)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_ev: chan %d not enabled\n", chan->id);
|
2021-10-18 12:47:51 +02:00
|
|
|
|
|
|
|
/* Cannot be dirty */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty != CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_ev: chan %d is dirty\n", chan->id);
|
2021-11-19 16:22:37 +01:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (ev <= 0)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_ev: cannot emit non-positive state %d\n", ev);
|
2021-11-19 16:22:37 +01:00
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->lastst >= 0 && chan->lastst == ev)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_ev id=%d cannot emit the state %d twice\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, ev);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
|
|
|
chan->ev = ev;
|
|
|
|
chan->t = *chan->clock;
|
2021-10-18 12:47:51 +02:00
|
|
|
|
2021-11-17 12:08:25 +01:00
|
|
|
mark_dirty(chan, CHAN_DIRTY_VALUE);
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
int
|
|
|
|
chan_get_st(struct ovni_chan *chan)
|
|
|
|
{
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->enabled == 0)
|
2021-10-21 16:15:29 +02:00
|
|
|
return chan->badst;
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->n == 0)
|
2021-10-21 16:41:52 +02:00
|
|
|
return 0;
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->n < 0)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_get_st: chan %d has negative n\n", chan->id);
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
return chan->stack[chan->n - 1];
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
2021-11-17 12:08:25 +01:00
|
|
|
static void
|
|
|
|
emit(struct ovni_chan *chan, int64_t t, int state)
|
|
|
|
{
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->dirty == CHAN_CLEAN)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("emit: chan %d is not dirty\n", chan->id);
|
2021-11-17 12:08:25 +01:00
|
|
|
|
|
|
|
/* 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?) */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->lastst != -1
|
|
|
|
&& chan->dirty == CHAN_DIRTY_VALUE
|
|
|
|
&& chan->lastst == state) {
|
2021-11-17 12:08:25 +01:00
|
|
|
/* TODO: Print the raw clock of the offending event */
|
2021-12-07 19:52:48 +01:00
|
|
|
die("emit: chan %d cannot emit the same state %d twice\n",
|
2022-09-29 15:34:44 +02:00
|
|
|
chan->id, state);
|
2021-11-17 12:08:25 +01:00
|
|
|
}
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->lastst != state) {
|
2021-11-17 12:08:25 +01:00
|
|
|
prv_ev(chan->prv, chan->row, t, chan->type, state);
|
|
|
|
|
|
|
|
chan->lastst = state;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
static void
|
|
|
|
emit_ev(struct ovni_chan *chan)
|
|
|
|
{
|
|
|
|
int new, last;
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (!chan->enabled)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("emit_ev: chan %d is not enabled\n", chan->id);
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->ev == -1)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("emit_ev: chan %d cannot emit -1 ev\n", chan->id);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
|
|
|
new = chan->ev;
|
|
|
|
last = chan_get_st(chan);
|
|
|
|
|
2022-09-29 15:34:44 +02:00
|
|
|
emit(chan, chan->t - 1, new);
|
2021-11-17 12:08:25 +01:00
|
|
|
emit(chan, chan->t, last);
|
2021-10-21 16:15:29 +02:00
|
|
|
|
|
|
|
chan->ev = -1;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
emit_st(struct ovni_chan *chan)
|
|
|
|
{
|
|
|
|
int st;
|
|
|
|
|
|
|
|
st = chan_get_st(chan);
|
|
|
|
|
2021-11-17 12:08:25 +01:00
|
|
|
emit(chan, chan->t, st);
|
2021-10-21 16:15:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Emits either the current state or punctual event in the PRV file */
|
|
|
|
void
|
|
|
|
chan_emit(struct ovni_chan *chan)
|
|
|
|
{
|
2022-09-29 15:34:44 +02:00
|
|
|
if (likely(chan->dirty == 0))
|
2021-10-21 16:15:29 +02:00
|
|
|
return;
|
|
|
|
|
2021-10-18 12:47:51 +02:00
|
|
|
dbg("chan_emit chan %d\n", chan->id);
|
2021-10-21 16:41:52 +02:00
|
|
|
|
2021-10-21 16:15:29 +02:00
|
|
|
/* Emit badst if disabled */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->enabled == 0) {
|
2021-10-21 16:15:29 +02:00
|
|
|
/* No punctual events allowed when disabled */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->ev != -1)
|
2021-12-07 19:52:48 +01:00
|
|
|
die("chan_emit: no punctual event allowed when disabled\n");
|
2021-10-21 16:15:29 +02:00
|
|
|
|
|
|
|
emit_st(chan);
|
|
|
|
goto shower;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Otherwise, emit punctual event if any or the state */
|
2022-09-29 15:34:44 +02:00
|
|
|
if (chan->ev != -1)
|
2021-10-21 16:15:29 +02:00
|
|
|
emit_ev(chan);
|
|
|
|
else
|
|
|
|
emit_st(chan);
|
|
|
|
|
|
|
|
shower:
|
|
|
|
chan->dirty = 0;
|
|
|
|
}
|