Skip to content

Commit

Permalink
Further simplified reviving objects.
Browse files Browse the repository at this point in the history
There is no need to have the global flag.
  • Loading branch information
shin1m committed Oct 23, 2024
1 parent 1b47c16 commit f69ac4a
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 28 deletions.
21 changes: 9 additions & 12 deletions include/recyclone/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ class t_engine
f_run();
}
};
//! The longest case after losing the last reference is missing an epoch -> skipping an epoch -> collected as a candidate cycle -> false reviving -> freed as a cycle.
static constexpr size_t V_COLLECTION_WAIT_COUNT = 5;

protected:
static inline RECYCLONE__THREAD t_engine* v_instance;
Expand All @@ -71,7 +73,6 @@ class t_engine
t_object<T_type>* v_cycles = nullptr;
t_heap<t_object<T_type>> v_object__heap;
size_t v_object__lower = 0;
bool v_object__reviving = false;
std::mutex v_object__reviving__mutex;
size_t v_object__release = 0;
size_t v_object__collect = 0;
Expand Down Expand Up @@ -201,12 +202,12 @@ class t_engine
void f_join_foregrounds();
//! Quits finalizer.
void f_quit_finalizer();
void f_revive(auto a_do)
auto f_revive(auto a_do)
{
std::lock_guard lock(v_object__reviving__mutex);
a_do([&](t_object<T_type>* a_p)
return a_do([&](t_object<T_type>* a_p)
{
v_object__reviving = a_p->v_reviving = true;
a_p->v_reviving = true;
});
}
};
Expand All @@ -221,10 +222,6 @@ void t_engine<T_type>::f_collector()
v_collector__conductor.f_next();
if (v_collector__conductor.v_quitting) break;
++v_collector__epoch;
{
std::lock_guard lock(v_object__reviving__mutex);
v_object__reviving = false;
}
{
std::lock_guard lock(v_thread__mutex);
size_t stack = 0;
Expand Down Expand Up @@ -260,7 +257,7 @@ void t_engine<T_type>::f_collector()
while (true) {
auto q = p->v_next;
if (q->v_type) {
if (q->v_color != e_color__ORANGE || q->v_cyclic > 0 || v_object__reviving && q->v_reviving) failed = true;
if (q->v_color != e_color__ORANGE || q->v_cyclic > 0 || q->v_reviving) failed = true;
q->v_reviving = false;
if (q->v_finalizee) finalizee = true;
p = q;
Expand Down Expand Up @@ -522,9 +519,9 @@ t_engine<T_type>::~t_engine()
f_finalize(v_thread__main);
v_collector__full.fetch_add(1, std::memory_order_relaxed);
#ifdef RECYCLONE__COOPERATIVE
for (size_t i = 0; i < 4; ++i) f__wait();
for (size_t i = 0; i < V_COLLECTION_WAIT_COUNT; ++i) f__wait();
#else
for (size_t i = 0; i < 4; ++i) f_wait();
for (size_t i = 0; i < V_COLLECTION_WAIT_COUNT; ++i) f_wait();
#endif
v_collector__conductor.f_quit();
assert(!v_thread__head);
Expand Down Expand Up @@ -572,7 +569,7 @@ template<typename T_type>
void t_engine<T_type>::f_collect()
{
v_collector__full.fetch_add(1, std::memory_order_relaxed);
for (size_t i = 0; i < 4; ++i) f_wait();
for (size_t i = 0; i < V_COLLECTION_WAIT_COUNT; ++i) f_wait();
v_collector__full.fetch_sub(1, std::memory_order_relaxed);
}

Expand Down
29 changes: 13 additions & 16 deletions test/extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -45,39 +45,36 @@ t_weak_pointer::t_weak_pointer(t_object_with_extension* a_target, t_object<t_typ

t_weak_pointer::~t_weak_pointer()
{
t_object<t_type>* p;
f_engine<t_type>()->f_revive([&](auto a_revive)
if (auto p = f_engine<t_type>()->f_revive([&](auto a_revive)
{
if ((p = f_detach())) a_revive(p);
});
if (p) t_slot<t_type>::f_decrement(p);
auto p = f_detach();
if (p) a_revive(p);
return p;
})) t_slot<t_type>::f_decrement(p);
if (v_dependent) t_slot<t_type>::f_decrement(v_dependent);
}

std::pair<t_object<t_type>*, t_object<t_type>*> t_weak_pointer::f_get() const
{
t_object<t_type>* p;
t_object<t_type>* q;
f_engine<t_type>()->f_revive([&](auto a_revive)
return f_engine<t_type>()->f_revive([&](auto a_revive)
{
if ((p = v_target)) a_revive(p);
q = v_dependent;
if (v_target) a_revive(v_target);
return std::make_pair(v_target, v_dependent);
});
return {p, q};
}

void t_weak_pointer::f_target__(t_object_with_extension* a_p)
{
t_root<t_slot<t_type>> dependent;
t_root<t_slot_of<t_object_with_extension>> p = a_p;
t_object<t_type>* q;
f_engine<t_type>()->f_revive([&](auto a_revive)
if (auto q = f_engine<t_type>()->f_revive([&](auto a_revive)
{
if (!a_p) v_dependent = dependent.f_raw().exchange(v_dependent, std::memory_order_relaxed);
if ((q = f_detach())) a_revive(q);
auto q = f_detach();
if (q) a_revive(q);
f_attach(p);
});
if (q) t_slot<t_type>::f_decrement(q);
return q;
})) t_slot<t_type>::f_decrement(q);
}

void t_weak_pointer::f_dependent__(t_object<t_type>* a_p)
Expand Down

0 comments on commit f69ac4a

Please sign in to comment.