6#include "dawn/prog/iomux.hxx"
10#include "dawn/debug.hxx"
11#include "dawn/io/common.hxx"
12#include "dawn/io/sdata.hxx"
29CProgIOMux::~CProgIOMux()
41 input.index = inputs.size();
42 inputs.push_back(input);
47int CProgIOMux::configureDesc(
const CDescObject &desc)
53 for (
size_t i = 0; i < desc.
getSize(); i++)
57 if (item->
cfgid.
s.
cls != CProgCommon::PROG_CLASS_IOMUX)
59 DAWNERR(
"iomux: unsupported cfg class 0x%" PRIx32
"\n", item->
cfgid.
v);
65 case PROG_IOMUX_CFG_CONTROL:
69 DAWNERR(
"iomux: CONTROL must have one item\n");
78 case PROG_IOMUX_CFG_INPUTS:
82 DAWNERR(
"iomux: INPUTS must not be empty\n");
86 for (
size_t j = 0; j < item->
cfgid.
s.
size; j++)
88 int ret = allocInput(ids[j].v);
97 case PROG_IOMUX_CFG_OUTPUT:
101 DAWNERR(
"iomux: OUTPUT must have one item\n");
111 DAWNERR(
"iomux: unsupported cfg id %u\n", item->
cfgid.
s.
id);
116 if (controlId == 0 || inputs.empty() || outputId == 0)
118 DAWNERR(
"iomux: control, inputs and output are required\n");
127 return configureDesc(
getDesc());
130int CProgIOMux::validateShape(
CIOCommon *io)
const
132 if (io ==
nullptr || output ==
nullptr)
149 control =
getIO(controlId);
150 if (control ==
nullptr || !control->
isRead() || !control->
isNotify() ||
153 DAWNERR(
"iomux: control 0x%" PRIx32
" must be scalar uint32 notify IO\n", controlId);
157 output =
getIO(outputId);
158 if (output ==
nullptr)
160 DAWNERR(
"iomux: output IO 0x%" PRIx32
" not found\n", outputId);
164 for (
auto &input : inputs)
166 input.io =
getIO(input.ioId);
167 if (input.io ==
nullptr)
169 DAWNERR(
"iomux: input IO 0x%" PRIx32
" not found\n", input.ioId);
174 int ret = prepareWritableTarget(output, inputs[0].io->
getDataDim(),
true);
177 DAWNERR(
"iomux: output prepare failed %d\n", ret);
181 for (
auto &input : inputs)
183 ret = validateShape(input.io);
186 DAWNERR(
"iomux: input 0x%" PRIx32
" incompatible\n", input.ioId);
192 if (dataBuf ==
nullptr)
213int CProgIOMux::controlNotifierCb(
void *priv,
io_ddata_t *data)
218 if (self ==
nullptr || !self->active || data ==
nullptr || data->
getItems() < 1)
223 std::memcpy(&index, data->
getDataPtr(),
sizeof(index));
224 self->routeIndex(index);
228int CProgIOMux::inputNotifierCb(
void *priv,
io_ddata_t *data)
230 SInput *input =
static_cast<SInput *
>(priv);
234 if (input ==
nullptr || input->owner ==
nullptr || !input->owner->active)
239 if (input->index == input->owner->currentIndex)
241 input->owner->routeIndex(
static_cast<uint32_t
>(input->index));
253 ret = control->setNotifier(controlNotifierCb, 0,
this);
256 DAWNERR(
"iomux: control setNotifier failed %d\n", ret);
260 for (
auto &input : inputs)
262 ret = input.io->setNotifier(inputNotifierCb, 0, &input);
265 DAWNERR(
"iomux: input setNotifier failed for 0x%" PRIx32
": %d\n", input.ioId, ret);
275 if (control->
getData(ctrlData, 1) == OK)
277 routeIndex(ctrlData(0));
286 if (control !=
nullptr)
288 control->setNotifier(
nullptr, 0,
nullptr);
290 for (
auto &input : inputs)
292 if (input.io !=
nullptr)
294 input.io->setNotifier(
nullptr, 0,
nullptr);
309void CProgIOMux::routeIndex(uint32_t index)
311 if (index >= inputs.size() || dataBuf ==
nullptr || output ==
nullptr)
316 currentIndex = index;
317 if (inputs[index].io->
getData(*dataBuf, 1) != OK)
322 int ret = output->
setData(*dataBuf);
325 DAWNERR(
"iomux: output setData failed %d\n", ret);
CIOCommon * getIO(SObjectId::ObjectId id)
Get an I/O object by ID.
void setObjectMapItem(SObjectId::ObjectId id, CObject *obj)
Set an item in the object map.
Descriptor wrapper for individual object configuration.
size_t getSize() const
Get number of configuration items for this object.
SObjectCfg::SObjectCfgItem * objectCfgItemNext(size_t &offset) const
Get config item at current offset and advance past it.
Base class for all I/O objects.
int setData(IODataCmn &data, size_t offset=0)
Set data for I/O (public interface with stats tracking).
int getData(IODataCmn &data, size_t len, size_t offset=0)
Get data from I/O (public interface with stats tracking).
virtual bool isNotify() const =0
Check if IO supports notifications.
bool isTimestamp() const
Check if I/O supports timestamp.
virtual size_t getDataDim() const =0
Get data vector dimension.
io_ddata_t * ddata_alloc(size_t batch, size_t chunk_size=0)
Allocate data buffer for this I/O.
virtual size_t getDataSize() const =0
Get data size in bytes.
virtual bool isRead() const =0
Check if IO supports read operations.
CDescObject & getDesc()
Get descriptor object for this object.
uint8_t getDtype() const
Get data type field.
Base class for all PROG (processing) objects.
IO multiplexer: routes selected input to one output.
bool hasThread() const
Check if a background thread is active.
int init()
One-time initialize object after bindings are resolved.
int configure()
Configure object from descriptor data.
int doStart()
Start implementation hook.
int deinit()
De-initialize object.
int doStop()
Stop implementation hook.
Out-of-tree user-extension hooks for Dawn.
Single configuration item within object.
ObjectCfgData_t data[]
Configuration data array (flexible, size from cfgid.s.size).
UObjectCfgId cfgid
Configuration ID header (type, class, id, size, rw, dtype).
@ DTYPE_UINT32
Unsigned 32-bit integer (0 to 4294967295).
uint32_t ObjectId
ObjectID type - single 32-bit value.
Heap-allocated dynamic I/O data buffer.
void * getDataPtr(size_t batch=0)
Get pointer to data only (skips timestamp if present).
size_t getItems()
Get number of items per batch.
Static (compile-time) I/O data buffer (no timestamp).
ObjectCfgId v
Raw 32-bit ConfigID value (for storage, comparison).
uint32_t cls
Object class (bits 21-29, max 511).
uint32_t id
Configuration identifier (bits 0-4, max 31).
uint32_t size
Configuration data size in 32-bit words (bits 5-14, max 1023).
struct dawn::SObjectCfg::UObjectCfgId::@10 s
Bit-field structure for named member access.
32-bit encoded object identifier (union with bit field).
ObjectId v
Raw 32-bit ObjectID value (for comparison, hashing, storage).