diff --git a/orbis-kernel/src/sys/sys_umtx.cpp b/orbis-kernel/src/sys/sys_umtx.cpp index 3a1cf57a2..776b08320 100644 --- a/orbis-kernel/src/sys/sys_umtx.cpp +++ b/orbis-kernel/src/sys/sys_umtx.cpp @@ -104,10 +104,12 @@ orbis::SysResult orbis::sys__umtx_op(Thread *thread, ptr obj, sint op, (ptr)uaddr1); case 8: { - return with_timeout([&](std::uint64_t ut) { - return umtx_cv_wait(thread, (ptr)obj, (ptr)uaddr1, ut, - val); - }); + return with_timeout( + [&](std::uint64_t ut) { + return umtx_cv_wait(thread, (ptr)obj, (ptr)uaddr1, ut, + val); + }, + false); } case 9: diff --git a/orbis-kernel/src/umtx.cpp b/orbis-kernel/src/umtx.cpp index 4b907b1a4..a9ec8e167 100644 --- a/orbis-kernel/src/umtx.cpp +++ b/orbis-kernel/src/umtx.cpp @@ -71,7 +71,11 @@ orbis::ErrorCode orbis::umtx_wait(Thread *thread, ptr addr, ulong id, val = reinterpret_cast>>(addr)->load(); if (val == id) { if (ut + 1 == 0) { - node->second.cv.wait(chain.mtx); + while (true) { + node->second.cv.wait(chain.mtx); + if (node->second.thr != thread) + break; + } } else { auto start = std::chrono::steady_clock::now(); std::uint64_t udiff = 0; @@ -162,8 +166,9 @@ static ErrorCode do_lock_normal(Thread *thread, ptr m, uint flags, auto node = chain.enqueue(key, thread); if (m->owner.compare_exchange_strong(owner, owner | kUmutexContested)) { node->second.cv.wait(chain.mtx, ut); - if (node->second.thr == thread) + if (node->second.thr == thread) { error = ErrorCode::TIMEDOUT; + } } if (node->second.thr == thread) chain.erase(node); @@ -298,7 +303,11 @@ orbis::ErrorCode orbis::umtx_cv_wait(Thread *thread, ptr cv, ErrorCode result = umtx_unlock_umutex(thread, m); if (result == ErrorCode{}) { if (ut + 1 == 0) { - node->second.cv.wait(chain.mtx, ut); + while (true) { + node->second.cv.wait(chain.mtx, ut); + if (node->second.thr != thread) + break; + } } else { auto start = std::chrono::steady_clock::now(); std::uint64_t udiff = 0;