Add SpMcRingBuffer to base class StimulusBuffer

This will hopefully genericise the interface for Stimbuffs.
This commit is contained in:
2025-11-01 00:06:42 -04:00
parent 5af7e531b6
commit cdade17905
4 changed files with 29 additions and 5 deletions
+8
View File
@@ -20,6 +20,14 @@ public:
: sequenceNo(0) : sequenceNo(0)
{} {}
~SequenceLock() = default;
// Non-copyable, non-movable (std::atomic is neither copyable nor movable)
SequenceLock(const SequenceLock&) = delete;
SequenceLock& operator=(const SequenceLock&) = delete;
SequenceLock(SequenceLock&&) = delete;
SequenceLock& operator=(SequenceLock&&) = delete;
/* Atomically increments sequenceNo and issues a release barrier. /* Atomically increments sequenceNo and issues a release barrier.
* Makes the sequence number odd, indicating a write is in progress. * Makes the sequence number odd, indicating a write is in progress.
*/ */
+7 -4
View File
@@ -2,6 +2,7 @@
#define _SP_MC_RING_BUFFER_H #define _SP_MC_RING_BUFFER_H
#include <vector> #include <vector>
#include <memory>
#include <cstddef> #include <cstddef>
#include <stdexcept> #include <stdexcept>
#include <algorithm> #include <algorithm>
@@ -44,8 +45,8 @@ public:
* locks array. * locks array.
*/ */
explicit SpMcRingBuffer( explicit SpMcRingBuffer(
const InputEngineConstraints& constraints_, size_t nSlots_,
size_t nSlots_) const InputEngineConstraints& constraints_)
: nSlots(nSlots_), strideNBytes(0), bufferNBytes(0), : nSlots(nSlots_), strideNBytes(0), bufferNBytes(0),
constraints(constraints_) constraints(constraints_)
{ {
@@ -59,7 +60,8 @@ public:
// Allocate data buffer: bufferNBytes (aligned up to alignment) // Allocate data buffer: bufferNBytes (aligned up to alignment)
data.resize(bufferNBytes); data.resize(bufferNBytes);
// Initialize sequence locks array: one lock per slot // Initialize sequence locks array: one lock per slot
sequenceLocks.resize(nSlots); // Use unique_ptr array since SequenceLock is not copyable or movable
sequenceLocks = std::make_unique<SequenceLock[]>(nSlots);
} }
~SpMcRingBuffer() = default; ~SpMcRingBuffer() = default;
@@ -121,7 +123,8 @@ private:
std::vector<uint8_t> data; std::vector<uint8_t> data;
// Sequence locks array: one lock per slot // Sequence locks array: one lock per slot
std::vector<SequenceLock> sequenceLocks; // Use unique_ptr array since SequenceLock is not copyable or movable
std::unique_ptr<SequenceLock[]> sequenceLocks;
public: public:
// Layout/invariants // Layout/invariants
+5
View File
@@ -13,6 +13,7 @@
#include <boost/asio/deadline_timer.hpp> #include <boost/asio/deadline_timer.hpp>
#include <spinLock.h> #include <spinLock.h>
#include <asynchronousBridge.h> #include <asynchronousBridge.h>
#include <user/spMcRingBuffer.h>
#include "stimFrame.h" #include "stimFrame.h"
#include "deviceAttachmentSpec.h" #include "deviceAttachmentSpec.h"
@@ -48,8 +49,11 @@ public:
public: public:
explicit StimulusBuffer( explicit StimulusBuffer(
const device::DeviceAttachmentSpec& deviceAttachmentSpec, const device::DeviceAttachmentSpec& deviceAttachmentSpec,
size_t nSlots,
const SpMcRingBuffer::InputEngineConstraints& ringBufferConstraints,
boost::asio::io_service& ioService) boost::asio::io_service& ioService)
: deviceAttachmentSpec(deviceAttachmentSpec), : deviceAttachmentSpec(deviceAttachmentSpec),
ringBuffer(nSlots, ringBufferConstraints),
ioService(ioService), ioService(ioService),
shouldContinue(false), timer(ioService) shouldContinue(false), timer(ioService)
{} {}
@@ -89,6 +93,7 @@ public:
protected: protected:
SpinLock frameAssemblyRateLimiter; SpinLock frameAssemblyRateLimiter;
SpMcRingBuffer ringBuffer;
private: private:
boost::asio::io_service& ioService; boost::asio::io_service& ioService;
@@ -1,5 +1,8 @@
#include <config.h>
#include <opts.h> #include <opts.h>
#include <algorithm> #include <algorithm>
#include <unistd.h>
#include <user/spMcRingBuffer.h>
#include <componentThread.h> #include <componentThread.h>
#include "pcloudStimulusBuffer.h" #include "pcloudStimulusBuffer.h"
@@ -11,7 +14,12 @@ PcloudStimulusBuffer::PcloudStimulusBuffer(
std::shared_ptr<livoxProto1::Device> &device, std::shared_ptr<livoxProto1::Device> &device,
const PcloudFormatDesc& formatDesc, const PcloudFormatDesc& formatDesc,
size_t nDgramsPerStagingBufferFrame) size_t nDgramsPerStagingBufferFrame)
: StimulusBuffer(deviceAttachmentSpec, device->componentThread->getIoService()), : StimulusBuffer(
deviceAttachmentSpec,
static_cast<size_t>((1000 * 30) / CONFIG_STIMBUFF_FRAME_PERIOD_MS),
SpMcRingBuffer::InputEngineConstraints(
static_cast<size_t>(sysconf(_SC_PAGE_SIZE)), 4),
device->componentThread->getIoService()),
deviceAttachmentSpec(deviceAttachmentSpec), device(device), deviceAttachmentSpec(deviceAttachmentSpec), device(device),
formatDesc(formatDesc), stagingBuffer( formatDesc(formatDesc), stagingBuffer(
StagingBuffer::InputEngineConstraints::ioUringConstraints, StagingBuffer::InputEngineConstraints::ioUringConstraints,