Thread: internal cleanup

Use different, simpler algorithm in wait_for.
Although the very idea of such notifications was rotten.
This commit is contained in:
Nekotekina 2020-03-03 17:53:27 +03:00
parent d594490329
commit 8d847d6f1c
2 changed files with 9 additions and 51 deletions

View file

@ -1921,48 +1921,12 @@ void thread_ctrl::_wait_for(u64 usec, bool alert /* true */)
} }
#endif #endif
std::unique_lock lock(_this->m_mutex, std::defer_lock); if (_this->m_signal && _this->m_signal.exchange(0))
while (true)
{ {
// Mutex is unlocked at the start and after the waiting
if (u32 sig = _this->m_signal.load())
{
if (sig & 1)
{
_this->m_signal &= ~1;
return;
}
}
if (usec == 0)
{
// No timeout: return immediately
return; return;
} }
if (!lock) _this->m_signal.wait(0, atomic_wait_timeout{usec <= 0xffff'ffff'ffff'ffff / 1000 ? usec * 1000 : 0xffff'ffff'ffff'ffff});
{
lock.lock();
}
// Double-check the value
if (u32 sig = _this->m_signal.load())
{
if (sig & 1)
{
_this->m_signal &= ~1;
return;
}
}
_this->m_cond.wait_unlock(usec, lock);
if (usec < cond_variable::max_timeout)
{
usec = 0;
}
}
} }
std::string thread_ctrl::get_name_cached() std::string thread_ctrl::get_name_cached()
@ -2012,11 +1976,11 @@ void thread_base::join() const
void thread_base::notify() void thread_base::notify()
{ {
if (!(m_signal & 1)) // Increment with saturation
if (m_signal.try_inc())
{ {
m_signal |= 1; // Considered impossible to have a situation when not notified
m_mutex.lock_unlock(); m_signal.notify_all();
m_cond.notify_one();
} }
} }

View file

@ -100,13 +100,7 @@ class thread_base
// Thread handle (platform-specific) // Thread handle (platform-specific)
atomic_t<std::uintptr_t> m_thread{0}; atomic_t<std::uintptr_t> m_thread{0};
// Thread mutex // Thread playtoy, that shouldn't be used
mutable shared_mutex m_mutex;
// Thread condition variable
cond_variable m_cond;
// Thread flags
atomic_t<u32> m_signal{0}; atomic_t<u32> m_signal{0};
// Thread state // Thread state