diff options
| author | 2021-04-11 12:49:18 -0700 | |
|---|---|---|
| committer | 2021-05-05 16:40:51 -0700 | |
| commit | 76a0814142b0f46374f1311515c1c870ac5f18e0 (patch) | |
| tree | 8050999a18ff0f9218e8d8149b1b14a8231c3cca /src/core/hle/kernel/svc.cpp | |
| parent | hle: kernel: KThread: Remove incorrect resource release. (diff) | |
| download | yuzu-76a0814142b0f46374f1311515c1c870ac5f18e0.tar.gz yuzu-76a0814142b0f46374f1311515c1c870ac5f18e0.tar.xz yuzu-76a0814142b0f46374f1311515c1c870ac5f18e0.zip | |
hle: kernel: svc: Migrate GetProcessId, CancelSynchronization, SetThreadActivity.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 80 |
1 files changed, 67 insertions, 13 deletions
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 5ead3a270..fae4c7209 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -390,17 +390,43 @@ static ResultCode GetThreadId32(Core::System& system, u32* out_thread_id_low, | |||
| 390 | } | 390 | } |
| 391 | 391 | ||
| 392 | /// Gets the ID of the specified process or a specified thread's owning process. | 392 | /// Gets the ID of the specified process or a specified thread's owning process. |
| 393 | static ResultCode GetProcessId(Core::System& system, u64* process_id, Handle handle) { | 393 | static ResultCode GetProcessId(Core::System& system, u64* out_process_id, Handle handle) { |
| 394 | __debugbreak(); | 394 | LOG_DEBUG(Kernel_SVC, "called handle=0x{:08X}", handle); |
| 395 | |||
| 396 | // Get the object from the handle table. | ||
| 397 | KScopedAutoObject obj = | ||
| 398 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KAutoObject>( | ||
| 399 | static_cast<Handle>(handle)); | ||
| 400 | R_UNLESS(obj.IsNotNull(), ResultInvalidHandle); | ||
| 401 | |||
| 402 | // Get the process from the object. | ||
| 403 | Process* process = nullptr; | ||
| 404 | if (Process* p = obj->DynamicCast<Process*>(); p != nullptr) { | ||
| 405 | // The object is a process, so we can use it directly. | ||
| 406 | process = p; | ||
| 407 | } else if (KThread* t = obj->DynamicCast<KThread*>(); t != nullptr) { | ||
| 408 | // The object is a thread, so we want to use its parent. | ||
| 409 | process = reinterpret_cast<KThread*>(obj.GetPointerUnsafe())->GetOwnerProcess(); | ||
| 410 | } else { | ||
| 411 | // TODO(bunnei): This should also handle debug objects before returning. | ||
| 412 | UNIMPLEMENTED_MSG("Debug objects not implemented"); | ||
| 413 | } | ||
| 414 | |||
| 415 | // Make sure the target process exists. | ||
| 416 | R_UNLESS(process != nullptr, ResultInvalidHandle); | ||
| 417 | |||
| 418 | // Get the process id. | ||
| 419 | *out_process_id = process->GetId(); | ||
| 420 | |||
| 395 | return ResultInvalidHandle; | 421 | return ResultInvalidHandle; |
| 396 | } | 422 | } |
| 397 | 423 | ||
| 398 | static ResultCode GetProcessId32(Core::System& system, u32* process_id_low, u32* process_id_high, | 424 | static ResultCode GetProcessId32(Core::System& system, u32* out_process_id_low, |
| 399 | Handle handle) { | 425 | u32* out_process_id_high, Handle handle) { |
| 400 | u64 process_id{}; | 426 | u64 out_process_id{}; |
| 401 | const auto result = GetProcessId(system, &process_id, handle); | 427 | const auto result = GetProcessId(system, &out_process_id, handle); |
| 402 | *process_id_low = static_cast<u32>(process_id); | 428 | *out_process_id_low = static_cast<u32>(out_process_id); |
| 403 | *process_id_high = static_cast<u32>(process_id >> 32); | 429 | *out_process_id_high = static_cast<u32>(out_process_id >> 32); |
| 404 | return result; | 430 | return result; |
| 405 | } | 431 | } |
| 406 | 432 | ||
| @@ -468,13 +494,21 @@ static ResultCode WaitSynchronization32(Core::System& system, u32 timeout_low, u | |||
| 468 | } | 494 | } |
| 469 | 495 | ||
| 470 | /// Resumes a thread waiting on WaitSynchronization | 496 | /// Resumes a thread waiting on WaitSynchronization |
| 471 | static ResultCode CancelSynchronization(Core::System& system, Handle thread_handle) { | 497 | static ResultCode CancelSynchronization(Core::System& system, Handle handle) { |
| 472 | __debugbreak(); | 498 | LOG_TRACE(Kernel_SVC, "called handle=0x{:X}", handle); |
| 499 | |||
| 500 | // Get the thread from its handle. | ||
| 501 | KScopedAutoObject thread = | ||
| 502 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>( | ||
| 503 | static_cast<Handle>(handle)); | ||
| 504 | |||
| 505 | // Cancel the thread's wait. | ||
| 506 | thread->WaitCancel(); | ||
| 473 | return RESULT_SUCCESS; | 507 | return RESULT_SUCCESS; |
| 474 | } | 508 | } |
| 475 | 509 | ||
| 476 | static ResultCode CancelSynchronization32(Core::System& system, Handle thread_handle) { | 510 | static ResultCode CancelSynchronization32(Core::System& system, Handle handle) { |
| 477 | return CancelSynchronization(system, thread_handle); | 511 | return CancelSynchronization(system, handle); |
| 478 | } | 512 | } |
| 479 | 513 | ||
| 480 | /// Attempts to locks a mutex | 514 | /// Attempts to locks a mutex |
| @@ -1032,7 +1066,27 @@ static ResultCode UnmapPhysicalMemory32(Core::System& system, u32 addr, u32 size | |||
| 1032 | /// Sets the thread activity | 1066 | /// Sets the thread activity |
| 1033 | static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, | 1067 | static ResultCode SetThreadActivity(Core::System& system, Handle thread_handle, |
| 1034 | ThreadActivity thread_activity) { | 1068 | ThreadActivity thread_activity) { |
| 1035 | __debugbreak(); | 1069 | LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, activity=0x{:08X}", thread_handle, |
| 1070 | thread_activity); | ||
| 1071 | |||
| 1072 | // Validate the activity. | ||
| 1073 | constexpr auto IsValidThreadActivity = [](ThreadActivity activity) { | ||
| 1074 | return activity == ThreadActivity::Runnable || activity == ThreadActivity::Paused; | ||
| 1075 | }; | ||
| 1076 | R_UNLESS(IsValidThreadActivity(thread_activity), ResultInvalidEnumValue); | ||
| 1077 | |||
| 1078 | // Get the thread from its handle. | ||
| 1079 | KScopedAutoObject thread = | ||
| 1080 | system.Kernel().CurrentProcess()->GetHandleTable().GetObject<KThread>(thread_handle); | ||
| 1081 | R_UNLESS(thread.IsNotNull(), ResultInvalidHandle); | ||
| 1082 | |||
| 1083 | // Check that the activity is being set on a non-current thread for the current process. | ||
| 1084 | R_UNLESS(thread->GetOwnerProcess() == system.Kernel().CurrentProcess(), ResultInvalidHandle); | ||
| 1085 | R_UNLESS(thread.GetPointerUnsafe() != GetCurrentThreadPointer(system.Kernel()), ResultBusy); | ||
| 1086 | |||
| 1087 | // Set the activity. | ||
| 1088 | R_TRY(thread->SetActivity(thread_activity)); | ||
| 1089 | |||
| 1036 | return RESULT_SUCCESS; | 1090 | return RESULT_SUCCESS; |
| 1037 | } | 1091 | } |
| 1038 | 1092 | ||