logmeow/arb.h

50 lines
1.0 KiB
C
Raw Normal View History

2023-01-18 16:34:17 +00:00
#pragma once
#include <atomic>
2023-01-21 08:54:30 +00:00
#define ARB_MAX_SIZE 255
2023-01-18 16:34:17 +00:00
template<typename T>
class AtomicRingBuffer {
public:
T* get();
void increment_read();
2023-01-21 07:51:23 +00:00
bool try_put_and_increment_write(T item);
2023-01-18 16:34:17 +00:00
private:
size_t _read = 0;
size_t _write = 0;
2023-01-21 08:54:30 +00:00
std::atomic<unsigned char> _used = 0;
2023-01-18 16:34:17 +00:00
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>
2023-01-21 07:51:23 +00:00
bool AtomicRingBuffer<T>::try_put_and_increment_write(T item) {
if (this->_used.load() == ARB_MAX_SIZE) {
return false;
2023-01-18 16:34:17 +00:00
}
this->_items[this->_write] = std::move(item);
++this->_used;
this->_write = (this->_write + 1) % ARB_MAX_SIZE;
2023-01-21 07:51:23 +00:00
return true;
2023-01-18 16:34:17 +00:00
}