From 8a7dc108924c3326bda1479372a77e64bb0dcf8e Mon Sep 17 00:00:00 2001 From: Hayodea Hekol Date: Fri, 14 Nov 2025 20:44:37 -0400 Subject: [PATCH] Split StimulusProducer=>StimulusBuffer+StimulusProducer We're getting ready for the last mile of the StimulusBuffer API and the proto-completion of the LivoxGen1 StimBuffApi. --- include/user/stimulusBuffer.h | 59 +++++++++++++++++++ include/user/stimulusProducer.h | 26 +------- stimBuffApis/livoxGen1/livoxGen1.cpp | 7 ++- stimBuffApis/livoxGen1/pcloudDataProducer.cpp | 33 +++++------ stimBuffApis/livoxGen1/pcloudDataProducer.h | 17 +++++- 5 files changed, 96 insertions(+), 46 deletions(-) create mode 100644 include/user/stimulusBuffer.h diff --git a/include/user/stimulusBuffer.h b/include/user/stimulusBuffer.h new file mode 100644 index 0000000..1581b84 --- /dev/null +++ b/include/user/stimulusBuffer.h @@ -0,0 +1,59 @@ +#ifndef _STIMULUS_BUFFER_H +#define _STIMULUS_BUFFER_H + +#include +#include +#include +#include +#include "stimulusFrame.h" + +namespace smo { +namespace stim_buff { + +// Forward declaration +class StimulusProducer; + +/** + * StimulusBuffer manages a collection of stimulus frames and ring buffer. + * + * This buffer holds the actual frame storage and ring buffer for stimulus + * data. It maintains a reference to the StimulusProducer that it owns. + */ +class StimulusBuffer +{ +public: + explicit StimulusBuffer( + std::shared_ptr &producer, + int histbuffMs, + const SpMcRingBuffer::InputEngineConstraints& ringBufferConstraints) + : producer(producer), + histbuffMs(histbuffMs), + frames_(static_cast(histbuffMs / CONFIG_STIMBUFF_FRAME_PERIOD_MS)), + ringBufferConstraints(ringBufferConstraints), + ringBuffer( + static_cast(histbuffMs / CONFIG_STIMBUFF_FRAME_PERIOD_MS), + ringBufferConstraints) + {} + + ~StimulusBuffer() = default; + + // Non-copyable, movable + StimulusBuffer(const StimulusBuffer&) = delete; + StimulusBuffer& operator=(const StimulusBuffer&) = delete; + StimulusBuffer(StimulusBuffer&&) = default; + StimulusBuffer& operator=(StimulusBuffer&&) = default; + +public: + std::shared_ptr producer; + std::vector frames_; + +protected: + int histbuffMs; + SpMcRingBuffer::InputEngineConstraints ringBufferConstraints; + SpMcRingBuffer ringBuffer; +}; + +} // namespace stim_buff +} // namespace smo + +#endif // _STIMULUS_BUFFER_H diff --git a/include/user/stimulusProducer.h b/include/user/stimulusProducer.h index 498c814..7d3ba59 100644 --- a/include/user/stimulusProducer.h +++ b/include/user/stimulusProducer.h @@ -14,8 +14,6 @@ #include #include #include -#include -#include "stimulusFrame.h" #include "deviceAttachmentSpec.h" namespace smo { @@ -33,29 +31,12 @@ namespace stim_buff { */ class StimulusProducer { -public: - class PcloudFormatDesc - { - public: - enum class Format - { - XYZ, - XYZI, - }; - - public: - Format format; - }; - public: explicit StimulusProducer( const std::shared_ptr &deviceAttachmentSpec, - size_t nSlots, - const SpMcRingBuffer::InputEngineConstraints& ringBufferConstraints, boost::asio::io_service& ioService_) : deviceAttachmentSpec(deviceAttachmentSpec), - ringBuffer(nSlots, ringBufferConstraints), ioService(ioService_), shouldContinue(false), timer(ioService), nDeferrals(0) @@ -86,6 +67,8 @@ public: { frameAssemblyRateLimiter.release(); } protected: + SpinLock frameAssemblyRateLimiter; + // Virtual functions for derived classes to override virtual int getStopDelayMs() const { @@ -99,11 +82,6 @@ private: public: std::shared_ptr deviceAttachmentSpec; - std::vector frames_; - -protected: - SpinLock frameAssemblyRateLimiter; - SpMcRingBuffer ringBuffer; private: boost::asio::io_service& ioService; diff --git a/stimBuffApis/livoxGen1/livoxGen1.cpp b/stimBuffApis/livoxGen1/livoxGen1.cpp index db973ef..483ef52 100644 --- a/stimBuffApis/livoxGen1/livoxGen1.cpp +++ b/stimBuffApis/livoxGen1/livoxGen1.cpp @@ -170,6 +170,7 @@ public: // Parse history buffer duration from quale-iface-api-params int histbuffMs = 30000; // Default: 30000ms (30 seconds) + (void)histbuffMs; const std::vector histbuffParamNames = { "history-buffer-duration-ms", "hist-buff-duration-ms", @@ -194,10 +195,10 @@ public: } // Create and add PcloudDataProducer to collection now that device is ready - StimulusProducer::PcloudFormatDesc formatDesc; - formatDesc.format = StimulusProducer::PcloudFormatDesc::Format::XYZI; + PcloudDataProducer::PcloudFormatDesc formatDesc; + formatDesc.format = PcloudDataProducer::PcloudFormatDesc::Format::XYZI; auto pcloudDataProducer = std::make_shared( - context->spec, context->deviceTmp, formatDesc, histbuffMs, 30); + context->spec, context->deviceTmp, formatDesc, 30); context->stimProducer = pcloudDataProducer; context->deviceTmp->nAttachedStimBuffs++; diff --git a/stimBuffApis/livoxGen1/pcloudDataProducer.cpp b/stimBuffApis/livoxGen1/pcloudDataProducer.cpp index 4932226..24e3312 100644 --- a/stimBuffApis/livoxGen1/pcloudDataProducer.cpp +++ b/stimBuffApis/livoxGen1/pcloudDataProducer.cpp @@ -23,12 +23,9 @@ PcloudDataProducer::PcloudDataProducer( const std::shared_ptr &deviceAttachmentSpec, std::shared_ptr &device, const PcloudFormatDesc& formatDesc, - int histbuffMs, size_t nDgramsPerStagingBufferFrame) : StimulusProducer( deviceAttachmentSpec, - static_cast(histbuffMs / CONFIG_STIMBUFF_FRAME_PERIOD_MS), - openClInputConstraints, device->componentThread->getIoService()), device(device), formatDesc(formatDesc), @@ -112,25 +109,25 @@ class PcloudDataProducer::ProduceFrameReq : public PostedAsynchronousContinuation { private: - PcloudDataProducer& stimBuff; + PcloudDataProducer& pcloudProducer; AsynchronousLoop frameAssemblyResult; StimulusFrame& stimulusFrame; public: ProduceFrameReq( - PcloudDataProducer& buffer, + PcloudDataProducer& producer, const std::shared_ptr& caller, Callback cb) : PostedAsynchronousContinuation(caller, cb), - stimBuff(buffer), + pcloudProducer(producer), frameAssemblyResult(0), - stimulusFrame(buffer.frames_[0]) + stimulusFrame(producer.tempStimulusFrame) {} public: void callOriginalCallback() { - stimBuff.allowNextStimulusFrame(); + pcloudProducer.allowNextStimulusFrame(); callOriginalCb(); } @@ -138,14 +135,14 @@ public: void produceFrameReq1_doAssemble_posted( std::shared_ptr context) { - SpinLock::Guard lock(stimBuff.shouldContinueLock); - if (!stimBuff.shouldContinue) + SpinLock::Guard lock(pcloudProducer.shouldContinueLock); + if (!pcloudProducer.shouldContinue) { callOriginalCallback(); return; } - stimBuff.ioUringAssemblyEngine.assembleFrameReq( + pcloudProducer.ioUringAssemblyEngine.assembleFrameReq( {context, std::bind( &ProduceFrameReq::produceFrameReq2_assembleDone, context.get(), context, @@ -156,8 +153,8 @@ public: std::shared_ptr context, bool success, AsynchronousLoop loop) { - SpinLock::Guard lock(stimBuff.shouldContinueLock); - if (!stimBuff.shouldContinue) + SpinLock::Guard lock(pcloudProducer.shouldContinueLock); + if (!pcloudProducer.shouldContinue) { callOriginalCallback(); return; @@ -172,7 +169,7 @@ public: context->frameAssemblyResult = loop; - stimBuff.openClCollatingAndMeshingEngine.compactCollateAndMeshFrameReq( + pcloudProducer.openClCollatingAndMeshingEngine.compactCollateAndMeshFrameReq( loop, stimulusFrame, {context, std::bind( &ProduceFrameReq::produceFrameReq3_compactCollateDone, @@ -184,8 +181,8 @@ public: [[maybe_unused]] std::shared_ptr context, bool success, StimulusFrame& /*stimulusFrame*/) { - SpinLock::Guard lock(stimBuff.shouldContinueLock); - if (!stimBuff.shouldContinue) + SpinLock::Guard lock(pcloudProducer.shouldContinueLock); + if (!pcloudProducer.shouldContinue) { callOriginalCallback(); return; @@ -198,8 +195,8 @@ public: } // Print kernel execution durations - auto compactDuration = stimBuff.openClCollatingAndMeshingEngine.getCompactKernelDuration(); - auto collateDuration = stimBuff.openClCollatingAndMeshingEngine.getCollateKernelDuration(); + auto compactDuration = pcloudProducer.openClCollatingAndMeshingEngine.getCompactKernelDuration(); + auto collateDuration = pcloudProducer.openClCollatingAndMeshingEngine.getCollateKernelDuration(); std::cout << __func__ << ": compactKernelDuration=" << compactDuration.count() << "ms, collateKernelDuration=" << collateDuration.count() << "ms" << std::endl; diff --git a/stimBuffApis/livoxGen1/pcloudDataProducer.h b/stimBuffApis/livoxGen1/pcloudDataProducer.h index 59d8c21..c43cd65 100644 --- a/stimBuffApis/livoxGen1/pcloudDataProducer.h +++ b/stimBuffApis/livoxGen1/pcloudDataProducer.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -25,12 +26,25 @@ namespace stim_buff { class PcloudDataProducer : public StimulusProducer { +public: + class PcloudFormatDesc + { + public: + enum class Format + { + XYZ, + XYZI, + }; + + public: + Format format; + }; + public: explicit PcloudDataProducer( const std::shared_ptr &deviceAttachmentSpec, std::shared_ptr &device, const PcloudFormatDesc& formatDesc, - int histbuffMs, size_t nDgramsPerStagingBufferFrame); ~PcloudDataProducer() = default; @@ -61,6 +75,7 @@ public: IoUringAssemblyEngine ioUringAssemblyEngine; StagingBuffer collationBuffer; std::atomic nAttachedStimBuffs{0}; + StimulusFrame tempStimulusFrame; private: class ProduceFrameReq;