Simple Collections
Loading...
Searching...
No Matches
SCCircularBuffer.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 https://www.thecoderscorner.com (Dave Cherry)
3 * This product is licensed under an Apache license, see the LICENSE file in the top-level directory.
4 */
5
6#ifndef SIMPLECOLLECTIONS_CIRCULARBUFFER_H
7#define SIMPLECOLLECTIONS_CIRCULARBUFFER_H
8
9#include <string.h>
10#include <inttypes.h>
11#include "SCThreadingSupport.h"
12
17
18namespace tccollection {
19
29
30 template<class T> class GenericCircularBuffer {
31 public:
32 enum BufferType { CIRCULAR_BUFFER, MEMORY_POOL };
33
34#ifdef SC_DEBUG_CHECKER
35 volatile uint32_t casExchangeSpins = 0;
36#endif
37
38 private:
39 position_t readerPosition;
40 position_t writerPosition;
41 const uint16_t bufferSize;
42 T *const buffer;
43 bool actingAsMemoryPool;
44
45 public:
46 explicit GenericCircularBuffer(uint16_t size, BufferType asMemPool = CIRCULAR_BUFFER) : readerPosition(0), writerPosition(0),
47 bufferSize(size), buffer(new T[size]), actingAsMemoryPool(asMemPool) {
48 atomicInitialisationSupport();
49 }
50 ~GenericCircularBuffer() { delete[] buffer; }
51
52 bool available() const { return actingAsMemoryPool || readerPosition != writerPosition; }
53 void put(const T& by) { buffer[nextPosition(&writerPosition)] = by; }
54 T& get() { return buffer[nextPosition(&readerPosition)]; }
55
56 int16_t nextPosition(position_ptr_t positionPtr) {
57 bool successfullyUpdated = false;
58 position_t existing;
59 while(!successfullyUpdated) {
60 existing = readAtomic(positionPtr);
61 position_t newPos = existing + 1;
62 if (newPos >= bufferSize) {
63 newPos = 0;
64 }
65 successfullyUpdated = casAtomic(positionPtr, existing, newPos);
66#ifdef SC_DEBUG_CHECKER
67 if(!successfullyUpdated) casExchangeSpins++;
68#endif
69 }
70 return existing;
71 }
72 };
73
74 class SCCircularBuffer {
75 private:
76 position_t readerPosition;
77 position_t writerPosition;
78 const uint16_t bufferSize;
79 uint8_t *const buffer;
80
81 public:
82 explicit SCCircularBuffer(uint16_t size);
83
84 ~SCCircularBuffer();
85
86 bool available() const { return readerPosition != writerPosition; }
87
88 void put(uint8_t by) { buffer[nextPosition(&writerPosition)] = by; }
89
90 uint8_t get() { return buffer[nextPosition(&readerPosition)]; }
91
92 private:
93 uint16_t nextPosition(position_ptr_t by);
94 };
95
96}
97
98
99
100#endif //SIMPLECOLLECTIONS_CIRCULARBUFFER_H
provides the thread safety implementation for circular buffers