diff options
| author | 2020-12-21 22:36:53 -0800 | |
|---|---|---|
| committer | 2021-01-11 14:23:16 -0800 | |
| commit | 35c3c078e3c079c0a9192b411e20c71b122ff057 (patch) | |
| tree | 572c0b6a47a249a78d658122de32908262ec6a69 /src/core/hle/kernel/svc.cpp | |
| parent | core: hle: kernel: Begin moving common SVC results to its own header. (diff) | |
| download | yuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.tar.gz yuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.tar.xz yuzu-35c3c078e3c079c0a9192b411e20c71b122ff057.zip | |
core: hle: kernel: Update KSynchronizationObject.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 47 |
1 files changed, 17 insertions, 30 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index de3ed25da..0a3064c7d 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "core/hle/kernel/handle_table.h" | 26 | #include "core/hle/kernel/handle_table.h" |
| 27 | #include "core/hle/kernel/k_scheduler.h" | 27 | #include "core/hle/kernel/k_scheduler.h" |
| 28 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 28 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 29 | #include "core/hle/kernel/k_synchronization_object.h" | ||
| 29 | #include "core/hle/kernel/kernel.h" | 30 | #include "core/hle/kernel/kernel.h" |
| 30 | #include "core/hle/kernel/memory/memory_block.h" | 31 | #include "core/hle/kernel/memory/memory_block.h" |
| 31 | #include "core/hle/kernel/memory/page_table.h" | 32 | #include "core/hle/kernel/memory/page_table.h" |
| @@ -38,7 +39,6 @@ | |||
| 38 | #include "core/hle/kernel/svc.h" | 39 | #include "core/hle/kernel/svc.h" |
| 39 | #include "core/hle/kernel/svc_types.h" | 40 | #include "core/hle/kernel/svc_types.h" |
| 40 | #include "core/hle/kernel/svc_wrap.h" | 41 | #include "core/hle/kernel/svc_wrap.h" |
| 41 | #include "core/hle/kernel/synchronization.h" | ||
| 42 | #include "core/hle/kernel/thread.h" | 42 | #include "core/hle/kernel/thread.h" |
| 43 | #include "core/hle/kernel/time_manager.h" | 43 | #include "core/hle/kernel/time_manager.h" |
| 44 | #include "core/hle/kernel/transfer_memory.h" | 44 | #include "core/hle/kernel/transfer_memory.h" |
| @@ -343,25 +343,14 @@ static ResultCode SendSyncRequest(Core::System& system, Handle handle) { | |||
| 343 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); | 343 | auto thread = kernel.CurrentScheduler()->GetCurrentThread(); |
| 344 | { | 344 | { |
| 345 | KScopedSchedulerLock lock(kernel); | 345 | KScopedSchedulerLock lock(kernel); |
| 346 | thread->InvalidateHLECallback(); | 346 | thread->SetState(ThreadStatus::WaitIPC); |
| 347 | thread->SetStatus(ThreadStatus::WaitIPC); | ||
| 348 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); | 347 | session->SendSyncRequest(SharedFrom(thread), system.Memory(), system.CoreTiming()); |
| 349 | } | 348 | } |
| 350 | 349 | ||
| 351 | if (thread->HasHLECallback()) { | 350 | Handle event_handle = thread->GetHLETimeEvent(); |
| 352 | Handle event_handle = thread->GetHLETimeEvent(); | 351 | if (event_handle != InvalidHandle) { |
| 353 | if (event_handle != InvalidHandle) { | 352 | auto& time_manager = kernel.TimeManager(); |
| 354 | auto& time_manager = kernel.TimeManager(); | 353 | time_manager.UnscheduleTimeEvent(event_handle); |
| 355 | time_manager.UnscheduleTimeEvent(event_handle); | ||
| 356 | } | ||
| 357 | |||
| 358 | { | ||
| 359 | KScopedSchedulerLock lock(kernel); | ||
| 360 | auto* sync_object = thread->GetHLESyncObject(); | ||
| 361 | sync_object->RemoveWaitingThread(SharedFrom(thread)); | ||
| 362 | } | ||
| 363 | |||
| 364 | thread->InvokeHLECallback(SharedFrom(thread)); | ||
| 365 | } | 354 | } |
| 366 | 355 | ||
| 367 | return thread->GetSignalingResult(); | 356 | return thread->GetSignalingResult(); |
| @@ -436,7 +425,7 @@ static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32* | |||
| 436 | } | 425 | } |
| 437 | 426 | ||
| 438 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds | 427 | /// Wait for the given handles to synchronize, timeout after the specified nanoseconds |
| 439 | static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, | 428 | static ResultCode WaitSynchronization(Core::System& system, s32* index, VAddr handles_address, |
| 440 | u64 handle_count, s64 nano_seconds) { | 429 | u64 handle_count, s64 nano_seconds) { |
| 441 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", | 430 | LOG_TRACE(Kernel_SVC, "called handles_address=0x{:X}, handle_count={}, nano_seconds={}", |
| 442 | handles_address, handle_count, nano_seconds); | 431 | handles_address, handle_count, nano_seconds); |
| @@ -458,28 +447,26 @@ static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr | |||
| 458 | } | 447 | } |
| 459 | 448 | ||
| 460 | auto& kernel = system.Kernel(); | 449 | auto& kernel = system.Kernel(); |
| 461 | Thread::ThreadSynchronizationObjects objects(handle_count); | 450 | std::vector<KSynchronizationObject*> objects(handle_count); |
| 462 | const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 451 | const auto& handle_table = kernel.CurrentProcess()->GetHandleTable(); |
| 463 | 452 | ||
| 464 | for (u64 i = 0; i < handle_count; ++i) { | 453 | for (u64 i = 0; i < handle_count; ++i) { |
| 465 | const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); | 454 | const Handle handle = memory.Read32(handles_address + i * sizeof(Handle)); |
| 466 | const auto object = handle_table.Get<SynchronizationObject>(handle); | 455 | const auto object = handle_table.Get<KSynchronizationObject>(handle); |
| 467 | 456 | ||
| 468 | if (object == nullptr) { | 457 | if (object == nullptr) { |
| 469 | LOG_ERROR(Kernel_SVC, "Object is a nullptr"); | 458 | LOG_ERROR(Kernel_SVC, "Object is a nullptr"); |
| 470 | return ERR_INVALID_HANDLE; | 459 | return ERR_INVALID_HANDLE; |
| 471 | } | 460 | } |
| 472 | 461 | ||
| 473 | objects[i] = object; | 462 | objects[i] = object.get(); |
| 474 | } | 463 | } |
| 475 | auto& synchronization = kernel.Synchronization(); | 464 | return KSynchronizationObject::Wait(kernel, index, objects.data(), |
| 476 | const auto [result, handle_result] = synchronization.WaitFor(objects, nano_seconds); | 465 | static_cast<s32>(objects.size()), nano_seconds); |
| 477 | *index = handle_result; | ||
| 478 | return result; | ||
| 479 | } | 466 | } |
| 480 | 467 | ||
| 481 | static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, | 468 | static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, |
| 482 | s32 handle_count, u32 timeout_high, Handle* index) { | 469 | s32 handle_count, u32 timeout_high, s32* index) { |
| 483 | const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; | 470 | const s64 nano_seconds{(static_cast<s64>(timeout_high) << 32) | static_cast<s64>(timeout_low)}; |
| 484 | return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds); | 471 | return WaitSynchronization(system, index, handles_address, handle_count, nano_seconds); |
| 485 | } | 472 | } |
| @@ -1655,7 +1642,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1655 | 1642 | ||
| 1656 | current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); | 1643 | current_thread->SetSynchronizationResults(nullptr, RESULT_TIMEOUT); |
| 1657 | 1644 | ||
| 1658 | if (thread->IsPendingTermination()) { | 1645 | if (thread->IsTerminationRequested()) { |
| 1659 | lock.CancelSleep(); | 1646 | lock.CancelSleep(); |
| 1660 | return ERR_THREAD_TERMINATING; | 1647 | return ERR_THREAD_TERMINATING; |
| 1661 | } | 1648 | } |
| @@ -1674,7 +1661,7 @@ static ResultCode WaitProcessWideKeyAtomic(Core::System& system, VAddr mutex_add | |||
| 1674 | current_thread->SetCondVarWaitAddress(condition_variable_addr); | 1661 | current_thread->SetCondVarWaitAddress(condition_variable_addr); |
| 1675 | current_thread->SetMutexWaitAddress(mutex_addr); | 1662 | current_thread->SetMutexWaitAddress(mutex_addr); |
| 1676 | current_thread->SetWaitHandle(thread_handle); | 1663 | current_thread->SetWaitHandle(thread_handle); |
| 1677 | current_thread->SetStatus(ThreadStatus::WaitCondVar); | 1664 | current_thread->SetState(ThreadStatus::WaitCondVar); |
| 1678 | current_process->InsertConditionVariableThread(SharedFrom(current_thread)); | 1665 | current_process->InsertConditionVariableThread(SharedFrom(current_thread)); |
| 1679 | } | 1666 | } |
| 1680 | 1667 | ||
| @@ -1761,7 +1748,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_ | |||
| 1761 | 1748 | ||
| 1762 | thread->SetLockOwner(nullptr); | 1749 | thread->SetLockOwner(nullptr); |
| 1763 | thread->SetSynchronizationResults(nullptr, RESULT_SUCCESS); | 1750 | thread->SetSynchronizationResults(nullptr, RESULT_SUCCESS); |
| 1764 | thread->ResumeFromWait(); | 1751 | thread->Wakeup(); |
| 1765 | } else { | 1752 | } else { |
| 1766 | // The mutex is already owned by some other thread, make this thread wait on it. | 1753 | // The mutex is already owned by some other thread, make this thread wait on it. |
| 1767 | const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); | 1754 | const Handle owner_handle = static_cast<Handle>(mutex_val & Mutex::MutexOwnerMask); |
| @@ -1769,7 +1756,7 @@ static void SignalProcessWideKey(Core::System& system, VAddr condition_variable_ | |||
| 1769 | auto owner = handle_table.Get<Thread>(owner_handle); | 1756 | auto owner = handle_table.Get<Thread>(owner_handle); |
| 1770 | ASSERT(owner); | 1757 | ASSERT(owner); |
| 1771 | if (thread->GetStatus() == ThreadStatus::WaitCondVar) { | 1758 | if (thread->GetStatus() == ThreadStatus::WaitCondVar) { |
| 1772 | thread->SetStatus(ThreadStatus::WaitMutex); | 1759 | thread->SetState(ThreadStatus::WaitMutex); |
| 1773 | } | 1760 | } |
| 1774 | 1761 | ||
| 1775 | owner->AddMutexWaiter(thread); | 1762 | owner->AddMutexWaiter(thread); |