SpMcRingBuff: Add getNextIndexForProducer/abortProduction
These two methods form the core of the SpMcRingbuffer's wrap-around behaviour.
This commit is contained in:
@@ -40,7 +40,8 @@ public:
|
||||
:
|
||||
nBuffers(frameAssemblyDesc_ ? frameAssemblyDesc_->slots.size() : 0),
|
||||
frameAssemblyDesc(frameAssemblyDesc_),
|
||||
slots(nBuffers) // Default-construct all frames
|
||||
slots(nBuffers), // Default-construct all frames
|
||||
producerNextUsableIndex(0)
|
||||
{
|
||||
if (!frameAssemblyDesc)
|
||||
{
|
||||
@@ -100,6 +101,42 @@ public:
|
||||
return slots[slotIndex].lock;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get the next index to produce into, atomically incrementing it
|
||||
*
|
||||
* Uses sequence lock to perform an emulated fetch_add with modulo nBuffers
|
||||
* applied, ensuring the returned index is always < nBuffers.
|
||||
*
|
||||
* @return The index to produce into (always < nBuffers)
|
||||
*/
|
||||
size_t getIndexToProduceInto()
|
||||
{
|
||||
producerNextUsableIndexLock.writeAcquire();
|
||||
size_t currentIndex = producerNextUsableIndex;
|
||||
size_t nextIndex = (currentIndex + 1) % nBuffers;
|
||||
producerNextUsableIndex = nextIndex;
|
||||
producerNextUsableIndexLock.writeRelease();
|
||||
return currentIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Abort production by setting the producer index to a specific value
|
||||
*
|
||||
* @param index The index to set (must be < nBuffers)
|
||||
* @throws std::out_of_range if index >= nBuffers
|
||||
*/
|
||||
void abortProduction(size_t index)
|
||||
{
|
||||
if (index >= nBuffers)
|
||||
{
|
||||
throw std::out_of_range(std::string(__func__)
|
||||
+ ": SpMcRingBuffer: index must be < nBuffers");
|
||||
}
|
||||
producerNextUsableIndexLock.writeAcquire();
|
||||
producerNextUsableIndex = index;
|
||||
producerNextUsableIndexLock.writeRelease();
|
||||
}
|
||||
|
||||
public:
|
||||
// Layout/invariants
|
||||
size_t nBuffers;
|
||||
@@ -109,6 +146,8 @@ private:
|
||||
std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc;
|
||||
// Frames vector: each frame contains a sequence lock and SlotDesc
|
||||
std::vector<StimulusFrame> slots;
|
||||
SequenceLock producerNextUsableIndexLock;
|
||||
size_t producerNextUsableIndex;
|
||||
};
|
||||
|
||||
} // namespace stim_buff
|
||||
|
||||
Reference in New Issue
Block a user