Improve emulation stopping speed

Split phases of signalling threads and joining them.
This commit is contained in:
Eladash 2021-06-05 22:15:15 +03:00 committed by Ivan
parent 2169e8d935
commit 76bf720adf
6 changed files with 109 additions and 39 deletions

View file

@ -612,20 +612,24 @@ public:
return static_cast<thread_state>(thread::m_sync.load() & 3);
}
// Try to abort by assigning thread_state::aborting (UB if assigning different state)
// Try to abort by assigning thread_state::aborting/finished
// Join thread by thread_state::finished
named_thread& operator=(thread_state s)
{
if (s == thread_state::aborting && thread::m_sync.fetch_op([](u64& v){ return !(v & 3) && (v |= 1); }).second)
if (s >= thread_state::aborting && thread::m_sync.fetch_op([](u64& v){ return !(v & 3) && (v |= 1); }).second)
{
if (s == thread_state::aborting)
{
thread::m_sync.notify_one(1);
}
thread::m_sync.notify_one(1);
if constexpr (std::is_base_of_v<need_wakeup, Context>)
{
this->wake_up();
}
if (s == thread_state::finished)
{
// This participates in emulation stopping, use destruction-alike semantics
thread::join(true);
}
}
return *this;
@ -634,9 +638,8 @@ public:
// Context type doesn't need virtual destructor
~named_thread()
{
// Assign aborting state forcefully
operator=(thread_state::aborting);
thread::join(true);
// Assign aborting state forcefully and join thread
operator=(thread_state::finished);
if constexpr (!result::empty)
{