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