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

Improve garbage_collector.hpp

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