50 lines
1.1 KiB
C++
50 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include "logcat_thread.h"
|
|
|
|
#define ARB_MAX_SIZE 16
|
|
|
|
template<typename T>
|
|
class AtomicRingBuffer {
|
|
public:
|
|
T* get();
|
|
void increment_read();
|
|
void put_and_increment_write(T item);
|
|
|
|
private:
|
|
size_t _read = 0;
|
|
size_t _write = 0;
|
|
std::atomic<size_t> _used = 0;
|
|
T _items[ARB_MAX_SIZE];
|
|
};
|
|
|
|
// function bodies must be in the header because https://stackoverflow.com/a/999383
|
|
|
|
template<typename T>
|
|
T* AtomicRingBuffer<T>::get() {
|
|
if (this->_used.load() == 0) {
|
|
return nullptr;
|
|
}
|
|
return &this->_items[this->_read];
|
|
}
|
|
|
|
template<typename T>
|
|
void AtomicRingBuffer<T>::increment_read() {
|
|
if (this->_used.load() == 0) {
|
|
return;
|
|
}
|
|
--this->_used;
|
|
this->_read = (this->_read + 1) % ARB_MAX_SIZE;
|
|
}
|
|
|
|
template<typename T>
|
|
void AtomicRingBuffer<T>::put_and_increment_write(T item) {
|
|
while (this->_used.load() == ARB_MAX_SIZE) {
|
|
printf("spinlocking!!!\n");
|
|
}
|
|
this->_items[this->_write] = std::move(item);
|
|
++this->_used;
|
|
this->_write = (this->_write + 1) % ARB_MAX_SIZE;
|
|
}
|