6#include "dawn/prog/bitsplit.hxx"
12#include "dawn/debug.hxx"
13#include "dawn/io/common.hxx"
14#include "dawn/io/ddata.hxx"
17using namespace dawn::prog;
26CProgBitSplit::~CProgBitSplit()
35 bind =
new (std::nothrow) SBitSplitBind();
42 bind->sourceId = sourceId;
43 bind->outputId = outputId;
44 bind->source =
nullptr;
45 bind->output =
nullptr;
46 bind->sourceData =
nullptr;
47 bind->outputData =
nullptr;
50 binds.push_back(bind);
56int CProgBitSplit::configureDesc(
const CDescObject &desc)
66 for (ii = 0; ii < desc.
getSize(); ii++)
70 if (item->
cfgid.
s.
cls != CProgCommon::PROG_CLASS_BITSPLIT)
72 DAWNERR(
"bitsplit: unsupported cfg class 0x%" PRIx32
"\n", item->
cfgid.
v);
78 case PROG_BITSPLIT_CFG_IOBIND:
80 nitems =
static_cast<size_t>(item->
cfgid.
s.
size);
81 if (nitems == 0 || nitems % 2 != 0)
83 DAWNERR(
"bitsplit: invalid IOBIND size %zu\n", nitems);
88 for (
size_t b = 0; b < nitems / 2; b++)
90 int ret = allocBind(ids[b * 2].v, ids[b * 2 + 1].v);
99 case PROG_BITSPLIT_CFG_BITS:
101 nitems =
static_cast<size_t>(item->
cfgid.
s.
size);
104 DAWNERR(
"bitsplit: BITS config must have at least one entry\n");
109 bitPositions.reserve(nitems);
110 for (
size_t i = 0; i < nitems; i++)
119 DAWNERR(
"bitsplit: unsupported cfg id %u\n", item->
cfgid.
s.
id);
127 DAWNERR(
"bitsplit: at least one IOBIND entry required\n");
131 if (binds.size() != bitPositions.size())
134 "bitsplit: IOBIND count (%zu) != BITS count (%zu)\n", binds.size(), bitPositions.size());
138 for (ii = 0; ii < binds.size(); ii++)
140 binds[ii]->bit = bitPositions[ii];
148 return configureDesc(
getDesc());
155 for (
auto bind : binds)
157 bind->source =
getIO(bind->sourceId);
160 DAWNERR(
"bitsplit: source IO 0x%" PRIx32
" not found\n", bind->sourceId);
164 if (!bind->source->isRead() || !isBitwiseDtype(bind->source->getDtype()))
166 DAWNERR(
"bitsplit: source IO 0x%" PRIx32
" is not readable bitwise IO\n", bind->sourceId);
170 bind->output =
getIO(bind->outputId);
173 DAWNERR(
"bitsplit: output IO 0x%" PRIx32
" not found\n", bind->outputId);
177 if (!isBitwiseDtype(bind->output->getDtype()))
179 DAWNERR(
"bitsplit: output IO 0x%" PRIx32
" unsupported dtype %u\n",
181 bind->output->getDtype());
185 ret = prepareWritableTarget(
186 bind->output, bind->output->getDataDim() == 0 ? 1 : bind->output->getDataDim(),
true);
189 DAWNERR(
"bitsplit: output target prepare failed %d\n", ret);
193 bind->sourceData = bind->source->ddata_alloc(1);
194 bind->outputData = bind->output->ddata_alloc(1);
195 if (!bind->sourceData || !bind->outputData)
197 DAWNERR(
"bitsplit: data allocation failed\n");
209 for (
auto bind : binds)
211 delete bind->sourceData;
212 delete bind->outputData;
217 bitPositions.clear();
221int CProgBitSplit::ioNotifierCb(
void *priv,
io_ddata_t *data)
223 SBitSplitBind *bind =
static_cast<SBitSplitBind *
>(priv);
225 if (!bind || !bind->owner || !bind->owner->active)
232 bind->owner->refreshSource(bind->sourceId);
244 for (
auto bind : binds)
246 if (!bind->source->isNotify())
251 ret = bind->source->setNotifier(ioNotifierCb, 0, bind);
255 "bitsplit: setNotifier failed for source 0x%" PRIx32
": %d\n", bind->sourceId, ret);
265 for (
auto bind : binds)
267 updateBind(bind,
nullptr);
277 for (
auto bind : binds)
279 if (bind->source && bind->source->isNotify())
281 bind->source->setNotifier(
nullptr, 0,
nullptr);
299 for (
auto bind : binds)
301 if (bind->sourceId == sourceId)
303 updateBind(bind,
nullptr);
308void CProgBitSplit::updateBind(SBitSplitBind *bind,
io_ddata_t *data)
315 if (!bind || !bind->source || !bind->output || !bind->sourceData || !bind->outputData)
323 bind->sourceData->getDataPtr(), data->
getDataPtr(), bind->sourceData->getDataSize());
327 ret = bind->source->getData(*bind->sourceData, 1);
330 DAWNERR(
"bitsplit: getData failed for source 0x%" PRIx32
": %d\n", bind->sourceId, ret);
335 srcBits = getLogicalBits(bind->source);
336 dstBits = getLogicalBits(bind->output);
338 if (
static_cast<size_t>(bind->bit) >= srcBits)
340 DAWNERR(
"bitsplit: start bit %" PRIu32
" out of range for 0x%" PRIx32
" (%zu bits)\n",
347 std::memset(bind->outputData->getDataPtr(), 0, bind->outputData->getDataSize());
349 for (bit = 0; bit < dstBits && static_cast<size_t>(bind->bit) + bit < srcBits; bit++)
352 bind->source, bind->sourceData->getDataPtr(),
static_cast<size_t>(bind->bit) + bit))
354 writeLogicalBit(bind->output, bind->outputData->getDataPtr(), bit,
true);
358 ret = bind->output->setData(*bind->outputData);
361 DAWNERR(
"bitsplit: 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.
CDescObject & getDesc()
Get descriptor object for this object.
int configure()
Configure object from descriptor data.
int doStart()
Start implementation hook.
int doStop()
Stop implementation hook.
int init()
One-time initialize object after bindings are resolved.
int deinit()
De-initialize object.
bool hasThread() const
Check if a background thread is active.
Base class for all PROG (processing) objects.
uint32_t ObjectCfgData_t
Configuration data element - single 32-bit word.
static uint32_t cfgToU32(ObjectCfgData_t x)
Convert ObjectCfgData_t to uint32_t.
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).
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.
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).