Commit 8020c3af authored by Xavier Thompson's avatar Xavier Thompson

Improve garbage_collector.hpp

parent b8fda6bb
......@@ -10,7 +10,7 @@
#include <typon/fundamental/deque.hpp>
#include <typon/fundamental/event_count.hpp>
#include <typon/fundamental/gc.hpp>
#include <typon/fundamental/garbage_collector.hpp>
#include <typon/fundamental/optional.hpp>
#include <typon/fundamental/random.hpp>
......@@ -27,7 +27,7 @@ namespace typon
using uint = unsigned int;
using Task = typename fdt::lock_free::deque<Continuation>::pop_type;
using Work = Worker::Work;
using GC = fdt::lock_free::gc;
using garbage_collector = fdt::lock_free::garbage_collector;
static inline thread_local uint thread_id;
......@@ -97,7 +97,7 @@ namespace typon
std::atomic_bool _done {false};
fdt::lock_free::event_count<> _notifyer;
const uint _concurrency;
GC _gc;
garbage_collector _gc;
Scheduler(uint concurrency) noexcept
: _worker(concurrency)
......@@ -149,7 +149,7 @@ namespace typon
void explore_work(Work & work) noexcept
{
_gc.enter(thread_id);
auto epoch = _gc.epoch(thread_id);
for (uint i = 0; i < _concurrency * 2 + 1; i++)
{
uint id = fdt::random::random() % _concurrency;
......@@ -159,12 +159,11 @@ namespace typon
break;
}
}
_gc.leave(thread_id);
}
void detect_work(Work & work) noexcept
{
_gc.enter(thread_id);
auto epoch = _gc.epoch(thread_id);
for (uint id = 0; id < _concurrency; id++)
{
work = _worker[id].try_steal();
......@@ -173,7 +172,6 @@ namespace typon
break;
}
}
_gc.leave(thread_id);
}
bool wait_for_work(Work & work) noexcept
......
......@@ -7,7 +7,7 @@
#include <variant>
#include <vector>
#include <typon/fundamental/gc.hpp>
#include <typon/fundamental/garbage_collector.hpp>
#include <typon/fundamental/optional.hpp>
#include <typon/fundamental/random.hpp>
......@@ -60,7 +60,7 @@ namespace typon
}
}
void resume(Work & work, fdt::lock_free::gc & gc) noexcept
void resume(Work & work, fdt::lock_free::garbage_collector & gc) noexcept
{
auto active = _active.load();
if (work._state == Work::Resumable)
......
#ifndef TYPON_FUNDAMENTAL_GC_HPP_INCLUDED
#define TYPON_FUNDAMENTAL_GC_HPP_INCLUDED
#ifndef TYPON_FUNDAMENTAL_GARBAGE_COLLECTOR_HPP_INCLUDED
#define TYPON_FUNDAMENTAL_GARBAGE_COLLECTOR_HPP_INCLUDED
#include <atomic>
#include <bit>
#include <cstdint>
#include <deque>
#include <type_traits>
#include <typon/fundamental/meta.hpp>
#include <typon/fundamental/ring_buffer.hpp>
namespace typon::fdt::lock_free
{
struct gc
struct garbage_collector
{
using u64 = std::uint_fast64_t;
using uint = unsigned int;
......@@ -54,7 +50,7 @@ namespace typon::fdt::lock_free
std::atomic<node *> _head;
std::atomic<node *> _tail;
gc(uint concurrency) noexcept
garbage_collector(uint concurrency) noexcept
: _concurrency(concurrency)
, _bits(std::bit_width(concurrency))
, _stamps(new std::atomic<u64>[concurrency])
......@@ -68,6 +64,23 @@ namespace typon::fdt::lock_free
}
}
auto epoch(uint id) noexcept
{
struct epoch
{
garbage_collector & _gc;
uint _id;
~epoch()
{
_gc.leave(_id);
}
};
enter(id);
return epoch { *this, id };
}
void enter(uint id) noexcept
{
auto state = _state.fetch_add((1 << _bits) + 1);
......@@ -136,7 +149,7 @@ namespace typon::fdt::lock_free
}
}
~gc()
~garbage_collector()
{
delete[] _stamps;
auto tail = _tail.load();
......@@ -151,4 +164,4 @@ namespace typon::fdt::lock_free
}
#endif // TYPON_FUNDAMENTAL_GC_HPP_INCLUDED
#endif // TYPON_FUNDAMENTAL_GARBAGE_COLLECTOR_HPP_INCLUDED
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