mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-05-06 05:00:03 +02:00
97 lines
2.7 KiB
C++
97 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include <chrono>
|
|
#include <fmt/color.h>
|
|
#include <fmt/format.h>
|
|
#include <memory>
|
|
#include <thread>
|
|
|
|
#include "aare/ProducerConsumerQueue.hpp"
|
|
|
|
namespace aare {
|
|
|
|
template <class ItemType> class CircularFifo {
|
|
uint32_t fifo_size;
|
|
aare::ProducerConsumerQueue<ItemType> free_slots;
|
|
aare::ProducerConsumerQueue<ItemType> filled_slots;
|
|
|
|
public:
|
|
CircularFifo() : CircularFifo(100){};
|
|
CircularFifo(uint32_t size) : fifo_size(size), free_slots(size + 1), filled_slots(size + 1) {
|
|
|
|
// TODO! how do we deal with alignment for writing? alignas???
|
|
// Do we give the user a chance to provide memory locations?
|
|
// Templated allocator?
|
|
for (size_t i = 0; i < fifo_size; ++i) {
|
|
free_slots.write(ItemType{});
|
|
}
|
|
}
|
|
|
|
bool next() {
|
|
// TODO! avoid default constructing ItemType
|
|
ItemType it;
|
|
if (!filled_slots.read(it))
|
|
return false;
|
|
if (!free_slots.write(std::move(it)))
|
|
return false;
|
|
return true;
|
|
}
|
|
|
|
~CircularFifo() {}
|
|
|
|
using value_type = ItemType;
|
|
|
|
auto numFilledSlots() const noexcept { return filled_slots.sizeGuess(); }
|
|
auto numFreeSlots() const noexcept { return free_slots.sizeGuess(); }
|
|
auto isFull() const noexcept { return filled_slots.isFull(); }
|
|
|
|
ItemType pop_free() {
|
|
ItemType v;
|
|
while (!free_slots.read(v))
|
|
;
|
|
return std::move(v);
|
|
// return v;
|
|
}
|
|
|
|
bool try_pop_free(ItemType &v) { return free_slots.read(v); }
|
|
|
|
ItemType pop_value(std::chrono::nanoseconds wait, std::atomic<bool> &stopped) {
|
|
ItemType v;
|
|
while (!filled_slots.read(v) && !stopped) {
|
|
std::this_thread::sleep_for(wait);
|
|
}
|
|
return std::move(v);
|
|
}
|
|
|
|
ItemType pop_value() {
|
|
ItemType v;
|
|
while (!filled_slots.read(v))
|
|
;
|
|
return std::move(v);
|
|
}
|
|
|
|
ItemType *frontPtr() { return filled_slots.frontPtr(); }
|
|
|
|
// TODO! Add function to move item from filled to free to be used
|
|
// with the frontPtr function
|
|
|
|
template <class... Args> void push_value(Args &&...recordArgs) {
|
|
while (!filled_slots.write(std::forward<Args>(recordArgs)...))
|
|
;
|
|
}
|
|
|
|
template <class... Args> bool try_push_value(Args &&...recordArgs) {
|
|
return filled_slots.write(std::forward<Args>(recordArgs)...);
|
|
}
|
|
|
|
template <class... Args> void push_free(Args &&...recordArgs) {
|
|
while (!free_slots.write(std::forward<Args>(recordArgs)...))
|
|
;
|
|
}
|
|
|
|
template <class... Args> bool try_push_free(Args &&...recordArgs) {
|
|
return free_slots.write(std::forward<Args>(recordArgs)...);
|
|
}
|
|
};
|
|
|
|
} // namespace aare
|