Files
salmanoff/stimBuffApis/livoxGen1/ioUringAssemblyEngine.h
T
hayodea b3743560bb IoUringAssmEngn: detect assembly end condition w/eventfdDesc validity
We can simplify and universalize the logic here by acknowledging that
assemblyCycleComplete() will always destroy the current eventfdDesc
object, so we can just check that to see whether we should continue
the assembly cycle.
2025-11-15 22:02:30 -04:00

116 lines
3.2 KiB
C++

#ifndef _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
#define _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H
#include <boostAsioLinkageFix.h>
#include <cstdint>
#include <cstddef>
#include <memory>
#include <functional>
#include <vector>
#include <chrono>
#include <atomic>
#include <random>
#include <liburing.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <boost/asio/posix/stream_descriptor.hpp>
#include <livoxProto1/device.h>
#include <asynchronousContinuation.h>
#include <asynchronousLoop.h>
#include <callback.h>
#include <spinLock.h>
#include <user/frameAssemblyDesc.h>
namespace smo {
namespace stim_buff {
class PcloudStimulusProducer;
class IoUringAssemblyEngine
{
public:
explicit IoUringAssemblyEngine(
PcloudStimulusProducer& parent, size_t nDgramsPerStagingBufferFrame);
~IoUringAssemblyEngine() = default;
bool setup();
void finalize();
typedef std::function<void(bool, AsynchronousLoop)> assembleFrameReqCbFn;
void assembleFrameReq(Callback<assembleFrameReqCbFn> cb);
// Telemetry helpers
static size_t computePointsPerDgram(int returnMode);
static size_t computePointsPerFrame(int returnMode, size_t nDgramsPerFrame)
{ return computePointsPerDgram(returnMode) * nDgramsPerFrame; }
static bool compactionIsNeeded(uint32_t nSucceeded, uint32_t nTotal)
{ return nSucceeded != 0 && nTotal != 0 && nSucceeded != nTotal; }
private:
typedef std::function<void(void*, int)> resetAndAssembleFrameCbFn;
void resetAndAssembleFrame(resetAndAssembleFrameCbFn onCqeReady);
void assemblyCycleComplete();
bool stop();
private:
PcloudStimulusProducer& parent;
// Cached descriptor for reuse across iterations
std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc;
// io_uring infrastructure
struct io_uring ring;
// Eventfd for CQE notifications (used with boost's unified loop)
int eventfdFd;
std::unique_ptr<boost::asio::posix::stream_descriptor> eventfdDesc;
uint64_t eventfd_value; // Buffer for async_read_some
// Point cloud data socket descriptor
std::shared_ptr<boost::asio::posix::stream_descriptor> pcloudDataFdDesc;
// Stall detection timer
boost::asio::deadline_timer stallTimer;
// Callback for CQE ntfns (called with user_data+result from each CQE)
resetAndAssembleFrameCbFn onCqeReadyCallback;
/** EXPLANATION:
* Flag to indicate whether engine should accept new requests.
* Set by setup(), cleared by stop().
*/
SpinLock shouldAcceptRequestsLock;
bool shouldAcceptRequests;
size_t nDgramsPerStagingBufferFrame;
struct SlotAssemblyDesc
{
bool assembled;
struct msghdr msgHdr;
struct iovec ioVec;
};
// Track which slots have been successfully assembled and maintain persistent iovecs
std::vector<SlotAssemblyDesc> assembledSlotsTracker;
// Random number generation for dummy slot creation
std::random_device randomDevice;
std::mt19937 randomGenerator;
void fillUnAssembledSlotsWithDummyDgrams();
void randomDummySlotFiller(AsynchronousLoop& loop);
void onEventfdRead(
const boost::system::error_code& error, std::size_t bytes_transferred);
class AssembleFrameReq;
friend class AssembleFrameReq;
public:
void printSlotBytes(size_t slotIndex, size_t nBytes);
};
} // namespace stim_buff
} // namespace smo
#endif // _LIVOX_GEN1_IOURING_ASSEMBLY_ENGINE_H