Commit 4954832c authored by Xavier Thompson's avatar Xavier Thompson

Separate ring logic from ring_buffer into binary_ring

parent 8020c3af
#ifndef TYPON_FUNDAMENTAL_BINARY_RING_HPP_INCLUDED
#define TYPON_FUNDAMENTAL_BINARY_RING_HPP_INCLUDED
#include <atomic>
#include <cstdint>
#include <type_traits>
namespace typon::fdt
{
template <typename I>
requires std::is_unsigned_v<I>
struct binary_ring
{
const I _mask;
binary_ring(std::uint_least8_t bits) noexcept
: _mask((I(1) << bits) - 1)
{}
I size() noexcept
{
return _mask + 1;
}
friend I operator % (I x, binary_ring ring) noexcept
{
return x & ring._mask;
}
};
}
#endif // TYPON_FUNDAMENTAL_BINARY_RING_HPP_INCLUDED
...@@ -6,6 +6,8 @@ ...@@ -6,6 +6,8 @@
#include <cstdint> #include <cstdint>
#include <type_traits> #include <type_traits>
#include <typon/fundamental/binary_ring.hpp>
namespace typon::fdt::lock_free namespace typon::fdt::lock_free
{ {
...@@ -19,12 +21,12 @@ namespace typon::fdt::lock_free ...@@ -19,12 +21,12 @@ namespace typon::fdt::lock_free
using enum std::memory_order; using enum std::memory_order;
const u64 _mask; binary_ring<u64> _ring;
ring_buffer * _next; ring_buffer * _next;
std::atomic<T> * const _array; std::atomic<T> * const _array;
ring_buffer(u8 bits, ring_buffer * next = nullptr) noexcept ring_buffer(u8 bits, ring_buffer * next = nullptr) noexcept
: _mask((u64(1) << bits) - 1) : _ring(bits)
, _next(next) , _next(next)
, _array(new std::atomic<T>[this->capacity()]) , _array(new std::atomic<T>[this->capacity()])
{} {}
...@@ -40,17 +42,17 @@ namespace typon::fdt::lock_free ...@@ -40,17 +42,17 @@ namespace typon::fdt::lock_free
u64 capacity() noexcept u64 capacity() noexcept
{ {
return _mask + 1; return _ring.size();
} }
void put(u64 index, T object) noexcept void put(u64 index, T object) noexcept
{ {
_array[index & _mask].store(std::move(object), relaxed); _array[index % _ring].store(std::move(object), relaxed);
} }
T get(u64 index) noexcept T get(u64 index) noexcept
{ {
return _array[index & _mask].load(relaxed); return _array[index % _ring].load(relaxed);
} }
ring_buffer * fill(ring_buffer * sink, u64 start, u64 end) noexcept ring_buffer * fill(ring_buffer * sink, u64 start, u64 end) noexcept
...@@ -64,7 +66,7 @@ namespace typon::fdt::lock_free ...@@ -64,7 +66,7 @@ namespace typon::fdt::lock_free
ring_buffer * grow(u64 start, u64 end) noexcept ring_buffer * grow(u64 start, u64 end) noexcept
{ {
auto buffer = new ring_buffer(std::countr_one(_mask) + 1, this); auto buffer = new ring_buffer(std::countr_zero(_ring.size()) + 1, this);
return fill(buffer, start, end); return fill(buffer, start, end);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment