Merge pull request #3226 from Subv/arbiter_timeout

HLE/AddressArbiter: Remove threads that were awoken by timeout from an Arbiter's waitlist
This commit is contained in:
Sebastian Valle 2017-12-06 12:11:23 -05:00 committed by GitHub
commit 4b1253b51a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -77,6 +77,15 @@ SharedPtr<AddressArbiter> AddressArbiter::Create(std::string name) {
ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, ArbitrationType type,
VAddr address, s32 value, u64 nanoseconds) {
auto timeout_callback = [this](ThreadWakeupReason reason, SharedPtr<Thread> thread,
SharedPtr<WaitObject> object) {
ASSERT(reason == ThreadWakeupReason::Timeout);
// Remove the newly-awakened thread from the Arbiter's waiting list.
waiting_threads.erase(std::remove(waiting_threads.begin(), waiting_threads.end(), thread),
waiting_threads.end());
};
switch (type) {
// Signal thread(s) waiting for arbitrate address...
@ -99,6 +108,7 @@ ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, Arbitratio
break;
case ArbitrationType::WaitIfLessThanWithTimeout:
if ((s32)Memory::Read32(address) < value) {
thread->wakeup_callback = timeout_callback;
thread->WakeAfterDelay(nanoseconds);
WaitThread(std::move(thread), address);
}
@ -117,6 +127,7 @@ ResultCode AddressArbiter::ArbitrateAddress(SharedPtr<Thread> thread, Arbitratio
if (memory_value < value) {
// Only change the memory value if the thread should wait
Memory::Write32(address, (s32)memory_value - 1);
thread->wakeup_callback = timeout_callback;
thread->WakeAfterDelay(nanoseconds);
WaitThread(std::move(thread), address);
}