mirror of
https://github.com/RPCSX/rpcsx.git
synced 2026-01-22 00:20:40 +01:00
[orbis-kernel] Fix evf waiting
This commit is contained in:
parent
55dfa5980d
commit
dcf585455d
|
|
@ -35,6 +35,8 @@ struct EventFlag final {
|
|||
std::uint64_t bitPattern;
|
||||
std::uint8_t waitMode;
|
||||
|
||||
bool operator==(const WaitingThread &) const = default;
|
||||
|
||||
bool test(std::uint64_t value) const {
|
||||
if (waitMode & kEvfWaitModeAnd) {
|
||||
return (value & bitPattern) == bitPattern;
|
||||
|
|
|
|||
|
|
@ -30,16 +30,24 @@ orbis::ErrorCode orbis::EventFlag::wait(Thread *thread, std::uint8_t waitMode,
|
|||
};
|
||||
|
||||
thread->evfResultPattern = 0;
|
||||
thread->evfIsCancelled = 0;
|
||||
thread->evfIsCancelled = -1;
|
||||
|
||||
std::unique_lock lock(queueMtx);
|
||||
while (true) {
|
||||
if (isDeleted) {
|
||||
if (thread->evfIsCancelled == UINT64_MAX)
|
||||
thread->evfResultPattern = value.load();
|
||||
return ErrorCode::ACCES;
|
||||
}
|
||||
if (thread->evfIsCancelled) {
|
||||
if (thread->evfIsCancelled == 1) {
|
||||
return ErrorCode::CANCELED;
|
||||
}
|
||||
if (thread->evfIsCancelled == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
thread->evfResultPattern = 0;
|
||||
thread->evfIsCancelled = -1;
|
||||
|
||||
auto waitingThread = WaitingThread{
|
||||
.thread = thread, .bitPattern = bitPattern, .waitMode = waitMode};
|
||||
|
|
@ -48,12 +56,11 @@ orbis::ErrorCode orbis::EventFlag::wait(Thread *thread, std::uint8_t waitMode,
|
|||
waitingThread.test(patValue)) {
|
||||
auto resultValue = waitingThread.applyClear(patValue);
|
||||
value.store(resultValue, std::memory_order::relaxed);
|
||||
thread->evfResultPattern = resultValue;
|
||||
thread->evfResultPattern = patValue;
|
||||
// Success
|
||||
break;
|
||||
}
|
||||
|
||||
if (timeout && *timeout == 0) {
|
||||
} else if (timeout && *timeout == 0) {
|
||||
thread->evfResultPattern = patValue;
|
||||
return ErrorCode::TIMEDOUT;
|
||||
}
|
||||
|
||||
|
|
@ -72,10 +79,13 @@ orbis::ErrorCode orbis::EventFlag::wait(Thread *thread, std::uint8_t waitMode,
|
|||
if (timeout) {
|
||||
thread->sync_cv.wait(queueMtx, *timeout);
|
||||
update_timeout();
|
||||
continue;
|
||||
} else {
|
||||
thread->sync_cv.wait(queueMtx);
|
||||
}
|
||||
|
||||
thread->sync_cv.wait(queueMtx);
|
||||
if (thread->evfIsCancelled == UINT64_MAX) {
|
||||
std::erase(waitingThreads, waitingThread);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: update thread state
|
||||
|
|
@ -98,7 +108,7 @@ orbis::ErrorCode orbis::EventFlag::tryWait(Thread *thread,
|
|||
waitingThread.test(patValue)) {
|
||||
auto resultValue = waitingThread.applyClear(patValue);
|
||||
value.store(resultValue, std::memory_order::relaxed);
|
||||
thread->evfResultPattern = resultValue;
|
||||
thread->evfResultPattern = patValue;
|
||||
return {};
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue