2023-01-12 19:16:52 +01:00
|
|
|
#include "emu/mux.h"
|
|
|
|
#include "common.h"
|
|
|
|
|
2023-01-11 12:08:28 +01:00
|
|
|
#define N 10
|
2023-01-12 19:16:52 +01:00
|
|
|
|
|
|
|
//static int
|
|
|
|
//select_active_thread(struct mux *mux,
|
|
|
|
// struct value *value,
|
|
|
|
// struct mux_input **input)
|
|
|
|
//{
|
|
|
|
// if (value->type == VALUE_NULL) {
|
|
|
|
// *input = NULL;
|
|
|
|
// return 0;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// if (value->type != VALUE_INT64) {
|
|
|
|
// err("expecting NULL or INT64 channel value\n");
|
|
|
|
// return -1;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// enum thread_state state = (enum thread_state) value->i;
|
|
|
|
//
|
|
|
|
// if (mux->ninputs != 1) {
|
|
|
|
// err("expecting NULL or INT64 channel value\n");
|
|
|
|
// return -1;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// switch (state) {
|
|
|
|
// case TH_ST_RUNNING:
|
|
|
|
// case TH_ST_COOLING:
|
|
|
|
// case TH_ST_WARMING:
|
|
|
|
// *input = only_input;
|
|
|
|
// break;
|
|
|
|
// case TH_ST_PAUSED:
|
|
|
|
// *input = NULL;
|
|
|
|
// break;
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// return 0;
|
|
|
|
//}
|
|
|
|
|
2023-01-10 18:30:51 +01:00
|
|
|
static void
|
|
|
|
check_output(struct mux *mux, struct value expected)
|
|
|
|
{
|
|
|
|
struct value out_value = value_null();
|
|
|
|
if (chan_read(mux->output, &out_value) != 0)
|
|
|
|
die("chan_read() failed for output channel\n");
|
|
|
|
|
|
|
|
if (!value_is_equal(&out_value, &expected)) {
|
|
|
|
char buf1[128];
|
|
|
|
char buf2[128];
|
|
|
|
die("unexpected value found %s in output (expected %s)\n",
|
|
|
|
value_str(out_value, buf1),
|
|
|
|
value_str(expected, buf2));
|
|
|
|
}
|
|
|
|
|
|
|
|
err("----- output ok -----\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_select(struct mux *mux, int key)
|
|
|
|
{
|
|
|
|
if (chan_set(mux->select, value_int64(key)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(1000 + key));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_input(struct mux *mux, int key)
|
|
|
|
{
|
|
|
|
/* Set the select channel to the selected key */
|
|
|
|
test_select(mux, key);
|
|
|
|
|
|
|
|
int new_value = 2000 + key;
|
|
|
|
|
|
|
|
/* Then change that channel */
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *mi = mux_get_input(mux, key);
|
2023-01-10 18:30:51 +01:00
|
|
|
if (mi == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input %d\n", key);
|
2023-01-10 18:30:51 +01:00
|
|
|
|
|
|
|
if (chan_set(mi->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_select_and_input(struct mux *mux, int key)
|
|
|
|
{
|
|
|
|
/* Set the select channel to the selected key, but don't
|
|
|
|
* propagate the changes yet */
|
|
|
|
if (chan_set(mux->select, value_int64(key)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
int new_value = 2000 + key;
|
|
|
|
|
|
|
|
/* Also change that channel */
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *mi = mux_get_input(mux, key);
|
2023-01-10 18:30:51 +01:00
|
|
|
if (mi == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input %d\n", key);
|
2023-01-10 18:30:51 +01:00
|
|
|
|
|
|
|
if (chan_set(mi->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
/* Write twice to the output */
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_input_and_select(struct mux *mux, int key)
|
|
|
|
{
|
|
|
|
int new_value = 2000 + key;
|
|
|
|
|
|
|
|
/* First change the input */
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *mi = mux_get_input(mux, key);
|
2023-01-10 18:30:51 +01:00
|
|
|
if (mi == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input %d\n", key);
|
2023-01-10 18:30:51 +01:00
|
|
|
|
|
|
|
if (chan_set(mi->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
/* Then change select */
|
|
|
|
if (chan_set(mux->select, value_int64(key)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
/* Write twice to the output */
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
test_mid_propagate(struct mux *mux, int key)
|
|
|
|
{
|
|
|
|
int new_value = 2000 + key;
|
|
|
|
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *mi = mux_get_input(mux, key);
|
2023-01-10 18:30:51 +01:00
|
|
|
if (mi == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input %d\n", key);
|
2023-01-10 18:30:51 +01:00
|
|
|
|
|
|
|
if (chan_set(mi->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
if (chan_set(mux->select, value_int64(key)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
}
|
|
|
|
|
2023-01-11 12:08:28 +01:00
|
|
|
static void
|
|
|
|
test_duplicate_output(struct mux *mux, int key1, int key2)
|
|
|
|
{
|
|
|
|
int new_value = 2000 + key1;
|
|
|
|
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *in1 = mux_get_input(mux, key1);
|
2023-01-11 12:08:28 +01:00
|
|
|
if (in1 == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input1 %d\n", key1);
|
2023-01-11 12:08:28 +01:00
|
|
|
|
2023-02-17 17:19:49 +01:00
|
|
|
struct mux_input *in2 = mux_get_input(mux, key2);
|
2023-01-11 12:08:28 +01:00
|
|
|
if (in2 == NULL)
|
2023-02-17 17:19:49 +01:00
|
|
|
die("mux_get_input failed to locate input2 %d\n", key2);
|
2023-01-11 12:08:28 +01:00
|
|
|
|
|
|
|
if (chan_set(in1->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (chan_set(in2->chan, value_int64(new_value)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
/* Select input 1 */
|
|
|
|
if (chan_set(mux->select, value_int64(key1)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
|
|
|
|
/* Now switch to input 2, which has the same value */
|
|
|
|
if (chan_set(mux->select, value_int64(key2)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
|
|
|
|
if (bay_propagate(mux->bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
|
|
|
check_output(mux, value_int64(new_value));
|
|
|
|
}
|
|
|
|
|
2023-01-10 18:30:51 +01:00
|
|
|
|
2023-01-12 19:16:52 +01:00
|
|
|
int
|
|
|
|
main(void)
|
|
|
|
{
|
|
|
|
struct bay bay;
|
|
|
|
bay_init(&bay);
|
|
|
|
|
|
|
|
struct chan inputs[N];
|
|
|
|
struct chan output;
|
|
|
|
struct chan select;
|
|
|
|
|
|
|
|
chan_init(&output, CHAN_SINGLE, "output");
|
|
|
|
chan_init(&select, CHAN_SINGLE, "select");
|
|
|
|
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
|
|
char buf[MAX_CHAN_NAME];
|
|
|
|
sprintf(buf, "input.%d", i);
|
|
|
|
chan_init(&inputs[i], CHAN_SINGLE, buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Register all channels in the bay */
|
2023-01-11 13:15:21 +01:00
|
|
|
if (bay_register(&bay, &select) != 0)
|
|
|
|
die("bay_register failed\n");
|
|
|
|
|
2023-01-12 19:16:52 +01:00
|
|
|
for (int i = 0; i < N; i++) {
|
2023-01-11 13:15:21 +01:00
|
|
|
if(bay_register(&bay, &inputs[i]) != 0)
|
|
|
|
die("bay_register failed\n");
|
2023-01-12 19:16:52 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
struct mux mux;
|
2023-01-11 13:15:21 +01:00
|
|
|
/* Attempt to init the mux without registering the output */
|
2023-02-17 17:19:49 +01:00
|
|
|
if (mux_init(&mux, &bay, &select, &output, NULL, N) == 0)
|
2023-01-11 13:15:21 +01:00
|
|
|
die("mux_init didn't fail\n");
|
|
|
|
|
|
|
|
if (bay_register(&bay, &output) != 0)
|
|
|
|
die("bay_register failed\n");
|
|
|
|
|
2023-02-17 17:19:49 +01:00
|
|
|
if (mux_init(&mux, &bay, &select, &output, NULL, N) != 0)
|
2023-01-11 13:15:21 +01:00
|
|
|
die("mux_init failed\n");
|
2023-01-12 19:16:52 +01:00
|
|
|
|
2023-01-16 15:42:59 +01:00
|
|
|
for (int i = 0; i < N; i++) {
|
2023-02-17 17:19:49 +01:00
|
|
|
if (mux_set_input(&mux, i, &inputs[i]) != 0)
|
2023-01-16 15:42:59 +01:00
|
|
|
die("mux_add_input failed\n");
|
|
|
|
}
|
2023-01-12 19:16:52 +01:00
|
|
|
|
|
|
|
/* Write something to the input channels */
|
|
|
|
for (int i = 0; i < N; i++) {
|
|
|
|
if (chan_set(&inputs[i], value_int64(1000 + i)) != 0)
|
|
|
|
die("chan_set failed\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Propagate values and call the callbacks */
|
|
|
|
if (bay_propagate(&bay) != 0)
|
|
|
|
die("bay_propagate failed\n");
|
|
|
|
|
2023-01-10 18:30:51 +01:00
|
|
|
test_select(&mux, 1);
|
|
|
|
test_input(&mux, 2);
|
|
|
|
test_select_and_input(&mux, 3);
|
|
|
|
test_input_and_select(&mux, 4);
|
|
|
|
test_mid_propagate(&mux, 5);
|
2023-01-11 12:08:28 +01:00
|
|
|
test_duplicate_output(&mux, 6, 7);
|
2023-01-12 19:16:52 +01:00
|
|
|
|
|
|
|
err("OK\n");
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|