Move SequenceLock into libspinscale

This commit is contained in:
2026-02-17 11:19:53 -04:00
parent 686bd6d38b
commit c0752b5e84
4 changed files with 6 additions and 82 deletions
-76
View File
@@ -1,76 +0,0 @@
#ifndef _SEQUENCE_LOCK_H
#define _SEQUENCE_LOCK_H
#include <atomic>
#include <optional>
namespace smo {
/**
* @brief Sequence lock synchronization primitive
*
* A reader-writer synchronization primitive where writers increment the
* sequence number (odd = writing in progress, even = stable) and readers
* check the sequence number to detect concurrent modifications.
*/
class SequenceLock
{
public:
SequenceLock()
: 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.
* Makes the sequence number odd, indicating a write is in progress.
*/
void writeAcquire()
{ sequenceNo.fetch_add(1, std::memory_order_release); }
/* Atomically increments sequenceNo and issues a release barrier.
* Makes the sequence number even again, indicating write is complete.
*/
void writeRelease()
{ sequenceNo.fetch_add(1, std::memory_order_release); }
/* Issues an acquire barrier and checks if the sequence number is even
* (stable state). If odd (writer active), returns nullopt. Otherwise
* returns the sequence number.
*
* @return std::nullopt if writer is active, otherwise the sequence number
*/
std::optional<size_t> readAcquire()
{
size_t seq = sequenceNo.load(std::memory_order_acquire);
if (seq & 1) {
return std::nullopt;
}
return seq;
}
/* Issues an acquire barrier and checks if the sequence number matches
* the original value from readAcquire(). If equal, the read was consistent.
*
* @param originalSequenceNo The sequence number obtained from readAcquire()
* @return true if read was consistent, false if writer modified during read
*/
bool readRelease(size_t originalSequenceNo)
{
size_t seq = sequenceNo.load(std::memory_order_acquire);
return seq == originalSequenceNo;
}
private:
std::atomic<size_t> sequenceNo;
};
} // namespace smo
#endif // _SEQUENCE_LOCK_H
+3 -3
View File
@@ -7,9 +7,9 @@
#include <string> #include <string>
#include <new> #include <new>
#include <memory> #include <memory>
#include <spinscale/sequenceLock.h>
#include <user/stimulusFrame.h> #include <user/stimulusFrame.h>
#include <user/frameAssemblyDesc.h> #include <user/frameAssemblyDesc.h>
#include <user/sequenceLock.h>
#include <user/senseApiDesc.h> #include <user/senseApiDesc.h>
#define CL_TARGET_OPENCL_VERSION 120 #define CL_TARGET_OPENCL_VERSION 120
#include <CL/cl.h> #include <CL/cl.h>
@@ -91,7 +91,7 @@ public:
return slots[slotIndex]; return slots[slotIndex];
} }
SequenceLock& getSequenceLockAtSlot(size_t slotIndex) sscl::SequenceLock& getSequenceLockAtSlot(size_t slotIndex)
{ {
if (slotIndex >= nBuffers) if (slotIndex >= nBuffers)
{ {
@@ -146,7 +146,7 @@ private:
std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc; std::shared_ptr<FrameAssemblyDesc> frameAssemblyDesc;
// Frames vector: each frame contains a sequence lock and SlotDesc // Frames vector: each frame contains a sequence lock and SlotDesc
std::vector<StimulusFrame> slots; std::vector<StimulusFrame> slots;
SequenceLock producerNextUsableIndexLock; sscl::SequenceLock producerNextUsableIndexLock;
size_t producerNextUsableIndex; size_t producerNextUsableIndex;
}; };
+2 -2
View File
@@ -3,8 +3,8 @@
#include <cstdint> #include <cstdint>
#include <memory> #include <memory>
#include <spinscale/sequenceLock.h>
#include <user/frameAssemblyDesc.h> #include <user/frameAssemblyDesc.h>
#include <user/sequenceLock.h>
#include <user/compute.h> #include <user/compute.h>
#include <user/senseApiDesc.h> #include <user/senseApiDesc.h>
#define CL_TARGET_OPENCL_VERSION 120 #define CL_TARGET_OPENCL_VERSION 120
@@ -110,7 +110,7 @@ public:
StimulusFrame& operator=(StimulusFrame&&) = default; StimulusFrame& operator=(StimulusFrame&&) = default;
public: public:
SequenceLock lock; sscl::SequenceLock lock;
SimultaneityStamp simultaneityStamp; SimultaneityStamp simultaneityStamp;
FrameAssemblyDesc::SlotDesc slotDesc; FrameAssemblyDesc::SlotDesc slotDesc;
std::shared_ptr<smo::compute::ClBuffer> clBuffer; std::shared_ptr<smo::compute::ClBuffer> clBuffer;