diff options
| author | 2018-01-06 16:14:12 -0500 | |
|---|---|---|
| committer | 2018-01-06 16:14:12 -0500 | |
| commit | 5017038ca72cbf061f43a3f30aa7e65e70463901 (patch) | |
| tree | a9fad792915c27fcbef74d30522a7ac6260185fb /src/core/hle/kernel/svc.cpp | |
| parent | semaphore: Updates for Switch. (diff) | |
| download | yuzu-5017038ca72cbf061f43a3f30aa7e65e70463901.tar.gz yuzu-5017038ca72cbf061f43a3f30aa7e65e70463901.tar.xz yuzu-5017038ca72cbf061f43a3f30aa7e65e70463901.zip | |
svc: Implement svcWaitProcessWideKeyAtomic.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 50 |
1 files changed, 49 insertions, 1 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 66df42da2..699d842fd 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -13,6 +13,7 @@ | |||
| 13 | #include "core/hle/kernel/object_address_table.h" | 13 | #include "core/hle/kernel/object_address_table.h" |
| 14 | #include "core/hle/kernel/process.h" | 14 | #include "core/hle/kernel/process.h" |
| 15 | #include "core/hle/kernel/resource_limit.h" | 15 | #include "core/hle/kernel/resource_limit.h" |
| 16 | #include "core/hle/kernel/semaphore.h" | ||
| 16 | #include "core/hle/kernel/svc.h" | 17 | #include "core/hle/kernel/svc.h" |
| 17 | #include "core/hle/kernel/svc_wrap.h" | 18 | #include "core/hle/kernel/svc_wrap.h" |
| 18 | #include "core/hle/kernel/sync_object.h" | 19 | #include "core/hle/kernel/sync_object.h" |
| @@ -471,6 +472,53 @@ static void SleepThread(s64 nanoseconds) { | |||
| 471 | Core::System::GetInstance().PrepareReschedule(); | 472 | Core::System::GetInstance().PrepareReschedule(); |
| 472 | } | 473 | } |
| 473 | 474 | ||
| 475 | /// Signal process wide key atomic | ||
| 476 | static ResultCode WaitProcessWideKeyAtomic(VAddr mutex_addr, VAddr semaphore_addr, | ||
| 477 | Handle thread_handle, s64 nano_seconds) { | ||
| 478 | LOG_TRACE(Kernel_SVC, | ||
| 479 | "called mutex_addr=%llx, semaphore_addr=%llx, thread_handle=0x%08X, timeout=%d", | ||
| 480 | mutex_addr, semaphore_addr, thread_handle, nano_seconds); | ||
| 481 | |||
| 482 | SharedPtr<Thread> thread = g_handle_table.Get<Thread>(thread_handle); | ||
| 483 | ASSERT(thread); | ||
| 484 | |||
| 485 | SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr); | ||
| 486 | if (!mutex) { | ||
| 487 | // Create a new mutex for the specified address if one does not already exist | ||
| 488 | mutex = Mutex::Create(thread, mutex_addr); | ||
| 489 | mutex->name = Common::StringFromFormat("mutex-%llx", mutex_addr); | ||
| 490 | } | ||
| 491 | |||
| 492 | SharedPtr<Semaphore> semaphore = g_object_address_table.Get<Semaphore>(semaphore_addr); | ||
| 493 | if (!semaphore) { | ||
| 494 | // Create a new semaphore for the specified address if one does not already exist | ||
| 495 | semaphore = Semaphore::Create(semaphore_addr, mutex_addr).Unwrap(); | ||
| 496 | semaphore->name = Common::StringFromFormat("semaphore-%llx", semaphore_addr); | ||
| 497 | } | ||
| 498 | |||
| 499 | ASSERT(semaphore->available_count == 0); | ||
| 500 | ASSERT(semaphore->mutex_addr == mutex_addr); | ||
| 501 | |||
| 502 | CASCADE_CODE(WaitSynchronization1( | ||
| 503 | semaphore, thread.get(), nano_seconds, | ||
| 504 | [mutex](ThreadWakeupReason reason, SharedPtr<Thread> thread, SharedPtr<WaitObject> object) { | ||
| 505 | ASSERT(thread->status == THREADSTATUS_WAIT_SYNCH_ANY); | ||
| 506 | |||
| 507 | if (reason == ThreadWakeupReason::Timeout) { | ||
| 508 | thread->SetWaitSynchronizationResult(RESULT_TIMEOUT); | ||
| 509 | return; | ||
| 510 | } | ||
| 511 | |||
| 512 | ASSERT(reason == ThreadWakeupReason::Signal); | ||
| 513 | thread->SetWaitSynchronizationResult(WaitSynchronization1(mutex, thread.get())); | ||
| 514 | thread->SetWaitSynchronizationOutput(thread->GetWaitObjectIndex(object.get())); | ||
| 515 | })); | ||
| 516 | |||
| 517 | mutex->Release(thread.get()); | ||
| 518 | |||
| 519 | return RESULT_SUCCESS; | ||
| 520 | } | ||
| 521 | |||
| 474 | /// Signal process wide key | 522 | /// Signal process wide key |
| 475 | static ResultCode SignalProcessWideKey(VAddr addr, u32 target) { | 523 | static ResultCode SignalProcessWideKey(VAddr addr, u32 target) { |
| 476 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, address=0x%llx, target=0x%08x", addr, target); | 524 | LOG_WARNING(Kernel_SVC, "(STUBBED) called, address=0x%llx, target=0x%08x", addr, target); |
| @@ -522,7 +570,7 @@ static const FunctionDef SVC_Table[] = { | |||
| 522 | {0x19, nullptr, "CancelSynchronization"}, | 570 | {0x19, nullptr, "CancelSynchronization"}, |
| 523 | {0x1A, SvcWrap<LockMutex>, "LockMutex"}, | 571 | {0x1A, SvcWrap<LockMutex>, "LockMutex"}, |
| 524 | {0x1B, SvcWrap<UnlockMutex>, "UnlockMutex"}, | 572 | {0x1B, SvcWrap<UnlockMutex>, "UnlockMutex"}, |
| 525 | {0x1C, nullptr, "WaitProcessWideKeyAtomic"}, | 573 | {0x1C, SvcWrap<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"}, |
| 526 | {0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"}, | 574 | {0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"}, |
| 527 | {0x1E, nullptr, "GetSystemTick"}, | 575 | {0x1E, nullptr, "GetSystemTick"}, |
| 528 | {0x1F, SvcWrap<ConnectToPort>, "ConnectToPort"}, | 576 | {0x1F, SvcWrap<ConnectToPort>, "ConnectToPort"}, |