summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc.cpp
diff options
context:
space:
mode:
authorGravatar bunnei2020-12-21 22:36:53 -0800
committerGravatar bunnei2021-01-11 14:23:16 -0800
commit35c3c078e3c079c0a9192b411e20c71b122ff057 (patch)
tree572c0b6a47a249a78d658122de32908262ec6a69 /src/core/hle/kernel/svc.cpp
parentcore: hle: kernel: Begin moving common SVC results to its own header. (diff)
downloadyuzu-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.cpp47
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
439static ResultCode WaitSynchronization(Core::System& system, Handle* index, VAddr handles_address, 428static 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
481static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u32 handles_address, 468static 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);