From f40a0a8d12aee873e5bfbde048ecf9261f43e5ad Mon Sep 17 00:00:00 2001 From: Rodrigo Arias Date: Wed, 11 Jan 2023 12:42:18 +0100 Subject: [PATCH] Prevent propagation loops --- src/emu/bay.c | 9 ++++++--- src/emu/bay.h | 1 + src/emu/mux.c | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 5 deletions(-) diff --git a/src/emu/bay.c b/src/emu/bay.c index a8f968b..c112f29 100644 --- a/src/emu/bay.c +++ b/src/emu/bay.c @@ -14,7 +14,11 @@ cb_chan_is_dirty(struct chan *chan, void *arg) struct bay_chan *bchan = arg; struct bay *bay = bchan->bay; - /* TODO: check duplicate? */ + if (bchan->is_dirty) { + err("channel %s already on dirty list\n", chan->name); + return -1; + } + DL_APPEND(bay->dirty, bchan); return 0; } @@ -94,8 +98,6 @@ bay_add_cb(struct bay *bay, struct chan *chan, bay_cb_func_t func, void *arg) return 0; } - - void bay_init(struct bay *bay) { @@ -142,6 +144,7 @@ bay_propagate(struct bay *bay) err("bay_propagate: chan_flush failed\n"); return -1; } + cur->is_dirty = 0; } bay->dirty = NULL; diff --git a/src/emu/bay.h b/src/emu/bay.h index 94114cf..2cada96 100644 --- a/src/emu/bay.h +++ b/src/emu/bay.h @@ -28,6 +28,7 @@ struct bay_chan { int ncallbacks; struct bay_cb *cb; struct bay *bay; + int is_dirty; /* Global hash table with all channels in bay */ UT_hash_handle hh; diff --git a/src/emu/mux.c b/src/emu/mux.c index 43f1492..b37b1b4 100644 --- a/src/emu/mux.c +++ b/src/emu/mux.c @@ -88,8 +88,6 @@ cb_input(struct chan *in_chan, void *ptr) { struct mux *mux = ptr; - /* TODO: We may need to cache the last read value from select to avoid - * problems reading the select channel too soon */ struct value sel_value; if (chan_read(mux->select, &sel_value) != 0) { err("cb_input: chan_read(select) failed\n"); @@ -139,6 +137,11 @@ mux_init(struct mux *mux, return -1; } + if (select == output) { + err("mux_init: cannot use same channel as select and output\n"); + return -1; + } + /* The output channel must accept multiple writes in the same * propagation phase while the channel is dirty, as we may write to the * input and select channel at the same time. */ @@ -178,6 +181,16 @@ mux_find_input(struct mux *mux, struct value value) int mux_add_input(struct mux *mux, struct value key, struct chan *chan) { + if (chan == mux->output) { + err("mux_init: cannot use same input channel as output\n"); + return -1; + } + + if (chan == mux->select) { + err("mux_init: cannot use same input channel as select\n"); + return -1; + } + if (mux_find_input(mux, key) != NULL) { char buf[128]; err("mux_add_input: input key %s already in mux\n",