IoUringAssmEngine: Add skeleton setup/finalize

Also add dependency on liburing.
This patch adds basic io_uring_queue_init and io_uring_exit
support and calls.
This commit is contained in:
2025-11-01 21:30:47 -04:00
parent 797a95e6a1
commit b2c73f6bed
3 changed files with 108 additions and 7 deletions
+8
View File
@@ -6,6 +6,9 @@ if(ENABLE_STIMBUFFAPI_livoxGen1)
# Set CONFIG variable for config.h
set(CONFIG_STIMBUFFAPI_LIVOXGEN1_ENABLED 1)
# Find liburing using pkg-config
pkg_check_modules(URING REQUIRED liburing)
add_library(livoxGen1 SHARED
livoxGen1.cpp
stagingBuffer.cpp
@@ -16,9 +19,14 @@ if(ENABLE_STIMBUFFAPI_livoxGen1)
target_include_directories(livoxGen1 PUBLIC
${Boost_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/commonLibs
${URING_INCLUDE_DIRS}
)
target_link_libraries(livoxGen1
${Boost_LIBRARIES}
${URING_LIBRARIES}
)
target_link_directories(livoxGen1 PUBLIC
${URING_LIBRARY_DIRS}
)
# Install rules
@@ -1,7 +1,9 @@
#include <cstring>
#include <sys/socket.h>
#include <boost/system/error_code.hpp>
#include <livoxProto1/device.h>
#include "ioUringAssemblyEngine.h"
#include "pcloudStimulusBuffer.h"
namespace smo {
namespace stim_buff {
@@ -22,16 +24,90 @@ struct DummyLivoxEthHeader
uint8_t timestamp[8];
};
IoUringAssemblyEngine::IoUringAssemblyEngine(PcloudStimulusBuffer& parent_)
: parent(parent_),
frameAssemblyDesc(nullptr), ring{},
isSetup(false),
stallTimer(parent_.device->componentThread->getIoService())
{}
bool IoUringAssemblyEngine::setup()
{
if (isSetup)
{ return false; }
// Get FrameAssemblyDesc from staging buffer
frameAssemblyDesc = static_cast<std::shared_ptr<FrameAssemblyDesc>>(
parent.stagingBuffer);
if (!frameAssemblyDesc || frameAssemblyDesc->slots.empty())
{ return false; }
// Get UDP socket file descriptor
int udpFd = parent.device->pcloudDataSocketDesc->native_handle();
if (udpFd < 0)
{ return false; }
/** EXPLANATION:
* Initialize io_uring ring - allocate SQEs and CQEs for one frame assembly
* One SQE per slot (one datagram per slot)
*/
int ret = io_uring_queue_init(
static_cast<unsigned int>(frameAssemblyDesc->numSlots), &ring, 0);
if (ret < 0)
{ return false; }
isSetup = true;
return true;
}
void IoUringAssemblyEngine::finalize()
{
// Call stop() to cancel in-flight operations (stop() already cancels the timer)
stop();
// Clean up io_uring ring if it was initialized
if (isSetup)
{
io_uring_queue_exit(&ring);
isSetup = false;
}
// Reset state to allow setup() to be called again
frameAssemblyDesc = nullptr;
}
void IoUringAssemblyEngine::resetAndAssembleFrame()
{
// Design/stub: This method should:
// 1. Submit frameAssemblyDesc->numSlots RECVMSG SQEs using io_uring_prep_recvmsg()
// - Each SQE receives into frameAssemblyDesc->slots[i].vaddr
// - With size frameAssemblyDesc->slots[i].nBytes
// - Socket FD from parent.device->pcloudDataSocketDesc->native_handle()
// 2. Submit batch via io_uring_submit(&ring)
// 3. Set up stall timer using stallTimer with appropriate timeout
// - SQEs are independent and can arrive out of order
// - Timer detects if SQEs get stalled
}
void IoUringAssemblyEngine::stop()
{
// Design/stub: This method should:
// 1. Cancel all pending SQEs using io_uring cancellation mechanisms
// 2. Cancel in-flight stall timeout timer via stallTimer.cancel()
// 3. Set appropriate state flags
}
void IoUringAssemblyEngine::cancelIncompleteAndFillDummies()
{
if (!desc)
if (!frameAssemblyDesc)
{ return; }
for (size_t i = 0; i < desc->numSlots; ++i)
for (size_t i = 0; i < frameAssemblyDesc->numSlots; ++i)
{
// In the real path, decide from CQE accounting whether slot i completed.
// Here, demonstrate dummy header insertion API.
auto* hdr = reinterpret_cast<DummyLivoxEthHeader*>(desc->slots[i].vaddr);
auto* hdr = reinterpret_cast<DummyLivoxEthHeader*>(frameAssemblyDesc->slots[i].vaddr);
hdr->err_code = DummyLivoxEthHeader::INVALID_ERR_CODE;
hdr->timestamp_type = DummyLivoxEthHeader::INVALID_TIMESTAMP_TYPE;
hdr->data_type = DummyLivoxEthHeader::INVALID_DATA_TYPE;
+21 -4
View File
@@ -8,28 +8,45 @@
#include <vector>
#include <chrono>
#include <atomic>
#include <liburing.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/deadline_timer.hpp>
#include <livoxProto1/device.h>
#include "frameAssemblyDesc.h"
namespace smo {
namespace stim_buff {
class PcloudStimulusBuffer;
class IoUringAssemblyEngine
{
public:
IoUringAssemblyEngine();
explicit IoUringAssemblyEngine(PcloudStimulusBuffer& parent);
~IoUringAssemblyEngine() = default;
bool setup();
void finalize();
void resetAndAssembleFrame();
void stop();
// Telemetry helpers
static size_t computePointsPerDgram(int returnMode);
static size_t computePointsPerFrame(int returnMode, size_t nDgramsPerFrame)
{ return computePointsPerDgram(returnMode) * nDgramsPerFrame; }
private:
PcloudStimulusBuffer& parent;
// Cached descriptor for reuse across iterations
FrameAssemblyDesc* desc;
std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc;
// io_uring infrastructure
struct io_uring ring;
bool isSetup;
// Stall detection timer
boost::asio::deadline_timer stallTimer;
void cancelIncompleteAndFillDummies();
};