Commit 351d221d authored by Xavier Thompson's avatar Xavier Thompson

gc.hpp: Count threads to allow immediate free

parent badc9889
...@@ -48,13 +48,15 @@ namespace typon::fdt::lock_free ...@@ -48,13 +48,15 @@ namespace typon::fdt::lock_free
}; };
const uint _concurrency; const uint _concurrency;
const uint _bits;
std::atomic<u64> * const _stamps; std::atomic<u64> * const _stamps;
std::atomic<u64> _stamp {0}; std::atomic<u64> _state {0};
std::atomic<node *> _head; std::atomic<node *> _head;
std::atomic<node *> _tail; std::atomic<node *> _tail;
gc(uint concurrency) noexcept gc(uint concurrency) noexcept
: _concurrency(concurrency) : _concurrency(concurrency)
, _bits(std::bit_width(concurrency))
, _stamps(new std::atomic<u64>[concurrency]) , _stamps(new std::atomic<u64>[concurrency])
{ {
auto first = new node(0); auto first = new node(0);
...@@ -68,20 +70,29 @@ namespace typon::fdt::lock_free ...@@ -68,20 +70,29 @@ namespace typon::fdt::lock_free
void enter(uint id) noexcept void enter(uint id) noexcept
{ {
_stamps[id].store(_stamp.fetch_add(1)); auto state = _state.fetch_add((1 << _bits) + 1);
_stamps[id].store(state >> _bits);
} }
template <typename T> template <typename T>
void retire(T * ptr) noexcept void retire(T * ptr) noexcept
{ {
auto stamp = _stamp.load(); auto state = _state.load();
auto node = new garbage<T> { ptr, stamp }; if ((state & ((1 << _bits) - 1)) == 0)
auto head = _head.exchange(node); {
head->_next.store(node); delete ptr;
}
else
{
auto node = new garbage<T> { ptr, state >> _bits };
auto head = _head.exchange(node);
head->_next.store(node);
}
} }
void leave(uint id) noexcept void leave(uint id) noexcept
{ {
_state.fetch_sub(1);
_stamps[id].store(u64(-1)); _stamps[id].store(u64(-1));
if (_tail.load()) if (_tail.load())
{ {
......
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