Commit aa27e875 authored by Xavier Thompson's avatar Xavier Thompson

WIP: gc: Improve optional and fix ring_buffer

parent d0a9f6aa
......@@ -58,7 +58,7 @@ namespace typon
Scheduler & scheduler = get();
Deque & deque = scheduler._deque[thread_id];
Task task = deque.pop();
if (task.match(Deque::Compress) || task.match(Deque::Prune))
if (task.match(Deque::Prune))
{
if (auto array = deque.shrink())
{
......@@ -175,7 +175,7 @@ namespace typon
}
auto key = _notifyer.prepare_wait();
task = _deque.back().steal();
if (!task.match(Deque::Empty))
if (task || task.match(Deque::Abort))
{
_notifyer.cancel_wait();
if (task)
......
......@@ -24,19 +24,19 @@ namespace typon::fdt::lock_free
using u8 = typename ring_buffer<T>::u8;
using u64 = typename ring_buffer<T>::u64;
static constexpr typename pop_type::template state<0> Empty {};
static constexpr typename pop_type::template state<2> Abort {};
static constexpr typename pop_type::template state<4> Compress {};
static constexpr typename pop_type::template state<3> Prune {};
static constexpr typename pop_type::template state<1> Abort {};
static constexpr typename pop_type::template state<2> Prune {};
using enum std::memory_order;
const u8 _bits;
std::atomic<u64> _top {1};
std::atomic<u64> _bottom {1};
std::atomic<array_type *> _array;
deque(u8 bits = 2) noexcept
: _array(new array_type(bits))
deque(u8 bits = 5) noexcept
: _bits(bits)
, _array(new array_type(bits))
{}
~deque()
......@@ -69,16 +69,7 @@ namespace typon::fdt::lock_free
_bottom.store(bottom, relaxed);
std::atomic_thread_fence(seq_cst);
u64 top = _top.load(relaxed);
u64 capacity = array->capacity();
pop_type x;
if (capacity > 16)
{
x = { Compress };
}
else
{
x = { Empty };
}
pop_type x {};
if (top <= bottom)
{
x = array->get(bottom);
......@@ -86,29 +77,20 @@ namespace typon::fdt::lock_free
{
if (!_top.compare_exchange_strong(top, top + 1, seq_cst, relaxed))
{
if (capacity > 16)
{
x = { Compress };
}
else
{
x = { Empty };
}
x = {};
}
_bottom.store(bottom + 1, relaxed);
}
if (capacity > 16 && bottom - top > capacity / 4)
{
if (x)
{
x = { *x, Prune };
}
}
}
else
{
_bottom.store(bottom + 1, relaxed);
}
u64 capacity = array->capacity();
if (capacity > u64(1) << _bits && capacity < (bottom - top) * 4)
{
x.set_state(Prune);
}
return x;
}
......@@ -141,7 +123,7 @@ namespace typon::fdt::lock_free
}
return { x };
}
return { Empty };
return {};
}
};
......
......@@ -14,12 +14,6 @@ namespace typon::fdt
template <unsigned char I>
using state = std::integral_constant<unsigned char, I>;
template <unsigned char I>
using empty_state = state<2 * I>;
template <unsigned char I>
using engaged_state = state<2 * I + 1>;
unsigned char _state;
union
{
......@@ -29,14 +23,15 @@ namespace typon::fdt
optional() noexcept : _state(0) {}
template <unsigned char I>
requires (!(I & 1))
optional(state<I> state) noexcept : _state(state) {}
optional(state<I> state) noexcept : _state(state() << 1 & (~1)) {}
optional(T value) noexcept : _state(1), _value(value) {}
template <unsigned char I>
requires (bool(I & 1))
optional(T value, state<I> state) noexcept : _state(state), _value(value) {}
optional(T value, state<I> state) noexcept
: _state((state() << 1) | 1)
, _value(value)
{}
~optional()
{
......@@ -54,7 +49,13 @@ namespace typon::fdt
template <unsigned char I>
bool match(state<I> state) noexcept
{
return state() == _state;
return state() == _state >> 1;
}
template <unsigned char I>
void set_state(state<I> state) noexcept
{
_state = (state() << 1) | (_state & 1);
}
T * operator->() noexcept
......
......@@ -63,9 +63,8 @@ namespace typon::fdt::lock_free
ring_buffer * shrink(u64 start, u64 end) noexcept
{
return nullptr;
u8 bits = std::countr_one(_mask);
if (bits < 3)
if (bits < 2)
{
return nullptr;
}
......
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