Implemented and fixed many issues
This commit is contained in:
@@ -78,6 +78,32 @@ public:
|
||||
/** @return Current number of stored points (≤ capacity). */
|
||||
uint32 Count() const;
|
||||
|
||||
/** @return Allocated capacity in points. */
|
||||
uint32 Capacity() const;
|
||||
|
||||
/**
|
||||
* @brief Enlarge the buffer to @p newCap points, keeping the stored data
|
||||
* and the TotalWritten() counter (unlike Allocate(), which resets both so
|
||||
* every reader cursor and every retained sample is lost).
|
||||
* @return true if the buffer now holds at least @p newCap points.
|
||||
*/
|
||||
bool Grow(uint32 newCap);
|
||||
|
||||
/**
|
||||
* @brief Wall-clock span currently retained, i.e. newest minus oldest
|
||||
* timestamp. 0 when fewer than two points are stored.
|
||||
*/
|
||||
float64 TimeSpan() const;
|
||||
|
||||
/**
|
||||
* @brief Timestamp of the most recently stored point, 0 when empty.
|
||||
*
|
||||
* This is the source's own time base, which is *not* the hub's wall clock:
|
||||
* use it, never clock_gettime(), whenever a decision depends on how far
|
||||
* the data itself has advanced.
|
||||
*/
|
||||
float64 NewestTime() const;
|
||||
|
||||
/** @brief Discard all stored points. */
|
||||
void Clear();
|
||||
|
||||
@@ -138,6 +164,69 @@ inline bool SignalRingBuffer::Allocate(uint32 maxPts) {
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool SignalRingBuffer::Grow(uint32 newCap) {
|
||||
if (newCap <= capacity) { return true; }
|
||||
|
||||
/* Allocate outside the lock; readers may be active. */
|
||||
float64 *newT = new float64[newCap];
|
||||
float64 *newV = new float64[newCap];
|
||||
if ((newT == static_cast<float64 *>(0)) ||
|
||||
(newV == static_cast<float64 *>(0))) {
|
||||
delete[] newT;
|
||||
delete[] newV;
|
||||
return false;
|
||||
}
|
||||
|
||||
(void) mutex.FastLock();
|
||||
if (newCap > capacity) {
|
||||
/* Copy oldest-to-newest so the new buffer starts unwrapped. */
|
||||
const uint32 avail = count;
|
||||
for (uint32 i = 0u; i < avail; i++) {
|
||||
const uint32 idx = (head + capacity - avail + i) % capacity;
|
||||
newT[i] = tBuf[idx];
|
||||
newV[i] = vBuf[idx];
|
||||
}
|
||||
float64 *oldT = tBuf;
|
||||
float64 *oldV = vBuf;
|
||||
tBuf = newT;
|
||||
vBuf = newV;
|
||||
capacity = newCap;
|
||||
head = avail;
|
||||
/* count and totalWritten are unchanged: no sample is gained or lost,
|
||||
* so push cursors stay valid across the resize. */
|
||||
mutex.FastUnLock();
|
||||
delete[] oldT;
|
||||
delete[] oldV;
|
||||
return true;
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
delete[] newT;
|
||||
delete[] newV;
|
||||
return true;
|
||||
}
|
||||
|
||||
inline float64 SignalRingBuffer::TimeSpan() const {
|
||||
(void) mutex.FastLock();
|
||||
float64 span = 0.0;
|
||||
if ((capacity > 0u) && (count > 1u)) {
|
||||
const uint32 oldest = (head + capacity - count) % capacity;
|
||||
const uint32 newest = (head + capacity - 1u) % capacity;
|
||||
span = tBuf[newest] - tBuf[oldest];
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
return (span > 0.0) ? span : 0.0;
|
||||
}
|
||||
|
||||
inline float64 SignalRingBuffer::NewestTime() const {
|
||||
(void) mutex.FastLock();
|
||||
float64 t = 0.0;
|
||||
if ((capacity > 0u) && (count > 0u)) {
|
||||
t = tBuf[(head + capacity - 1u) % capacity];
|
||||
}
|
||||
mutex.FastUnLock();
|
||||
return t;
|
||||
}
|
||||
|
||||
inline void SignalRingBuffer::Write(float64 t, float64 v) {
|
||||
(void) mutex.FastLock();
|
||||
if (capacity > 0u) {
|
||||
@@ -288,6 +377,13 @@ inline MARTe::uint64 SignalRingBuffer::TotalWritten() const {
|
||||
return tw;
|
||||
}
|
||||
|
||||
inline uint32 SignalRingBuffer::Capacity() const {
|
||||
(void) mutex.FastLock();
|
||||
const uint32 c = capacity;
|
||||
mutex.FastUnLock();
|
||||
return c;
|
||||
}
|
||||
|
||||
inline uint32 SignalRingBuffer::Count() const {
|
||||
(void) mutex.FastLock();
|
||||
uint32 c = count;
|
||||
|
||||
Reference in New Issue
Block a user