diff --git a/src/RingBuf.h b/src/RingBuf.h index c4af8c9..9c4cbf1 100644 --- a/src/RingBuf.h +++ b/src/RingBuf.h @@ -114,6 +114,14 @@ class RingBuf { bool push(const ET inElement) __attribute__((noinline)); /* Push a data at the end of the buffer. Copy it from its pointer */ bool push(const ET *const inElement) __attribute__((noinline)); + /* Push a data at the beginning (head) of the buffer */ + bool pushFront(const ET inElement) __attribute__((noinline)); + /* Push a data at the beginning (head) of the buffer. Copy it from its pointer */ + bool pushFront(const ET *const inElement) __attribute__((noinline)); + /* Push a data at the beginning and overwrite the older data at the end if full */ + bool pushFrontOverwrite(const ET inElement) __attribute__((noinline)); + /* Push a data at the beginning and overwrite the older data at the end if full. Copy it from its pointer */ + bool pushFrontOverwrite(const ET *const inElement) __attribute__((noinline)); /* Push a data at the end of the buffer with interrupts disabled */ bool lockedPush(const ET inElement); /* Push a data at the end of the buffer with interrupts disabled. Copy it from @@ -125,6 +133,14 @@ class RingBuf { /* Push a data in the buffer and overwrite the older data if any with * interrupts disabled. Copy it from its pointer */ bool lockedPushOverwrite(const ET *const inElement); + /* Push a data at the beginning with interrupts disabled */ + bool lockedPushFront(const ET inElement); + /* Push a data at the beginning with interrupts disabled. Copy it from its pointer */ + bool lockedPushFront(const ET *const inElement); + /* Push a data at the beginning and overwrite if full with interrupts disabled */ + bool lockedPushFrontOverwrite(const ET inElement); + /* Push a data at the beginning and overwrite if full with interrupts disabled. Copy it from its pointer */ + bool lockedPushFrontOverwrite(const ET *const inElement); /* Pop the data at the beginning of the buffer */ bool pop(ET &outElement) __attribute__((noinline)); /* Pop the data at the beginning of the buffer with interrupt disabled */ @@ -191,6 +207,72 @@ bool RingBuf::push(const ET *const inElement) { return true; } +/* + * Push at the beginning (head) of the buffer. + * If the buffer is full, returns false and does not modify the buffer. + */ +template +bool RingBuf::pushFront(const ET inElement) { + if (isFull()) + return false; + if (mReadIndex == 0) + mReadIndex = S - 1; + else + mReadIndex--; + mBuffer[mReadIndex] = inElement; + mSize++; + return true; +} + +template +bool RingBuf::pushFront(const ET *const inElement) { + if (isFull()) + return false; + if (mReadIndex == 0) + mReadIndex = S - 1; + else + mReadIndex--; + mBuffer[mReadIndex] = *inElement; + mSize++; + return true; +} + +/* + * Push at the beginning (head) of the buffer, overwriting the oldest tail + * element if the buffer is full. Mirrors pushOverwrite() semantics: + * returns false when an overwrite happened, true otherwise. + */ +template +bool RingBuf::pushFrontOverwrite(const ET inElement) { + if (mReadIndex == 0) + mReadIndex = S - 1; + else + mReadIndex--; + mBuffer[mReadIndex] = inElement; + if (isFull()) { + // size stays S; we've effectively dropped the former last element + return false; + } else { + mSize++; + return true; + } +} + +template +bool RingBuf::pushFrontOverwrite(const ET *const inElement) { + if (mReadIndex == 0) + mReadIndex = S - 1; + else + mReadIndex--; + mBuffer[mReadIndex] = *inElement; + if (isFull()) { + return false; + } else { + mSize++; + return true; + } +} + template bool RingBuf::pushOverwrite(const ET inElement) { mBuffer[writeIndex()] = inElement; @@ -231,6 +313,38 @@ bool RingBuf::lockedPush(const ET *const inElement) { return result; } +template +bool RingBuf::lockedPushFront(const ET inElement) { + noInterrupts(); + bool result = pushFront(inElement); + interrupts(); + return result; +} + +template +bool RingBuf::lockedPushFront(const ET *const inElement) { + noInterrupts(); + bool result = pushFront(inElement); + interrupts(); + return result; +} + +template +bool RingBuf::lockedPushFrontOverwrite(const ET inElement) { + noInterrupts(); + bool result = pushFrontOverwrite(inElement); + interrupts(); + return result; +} + +template +bool RingBuf::lockedPushFrontOverwrite(const ET *const inElement) { + noInterrupts(); + bool result = pushFrontOverwrite(inElement); + interrupts(); + return result; +} + template bool RingBuf::lockedPushOverwrite(const ET inElement) { noInterrupts();