diff options
author | Liam <byteslice@airmail.cc> | 2023-08-15 00:12:06 +0200 |
---|---|---|
committer | Liam <byteslice@airmail.cc> | 2023-08-15 00:12:06 +0200 |
commit | 0bd9a4456c49b1e5de8f659682a814bb4b5854d2 (patch) | |
tree | 1a9575d019cbab012f2dd3f56675be604737f79a /src/core/hle/kernel/svc | |
parent | Merge pull request #11282 from ameerj/glasm-xfb (diff) | |
download | yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar.gz yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar.bz2 yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar.lz yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar.xz yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.tar.zst yuzu-0bd9a4456c49b1e5de8f659682a814bb4b5854d2.zip |
Diffstat (limited to 'src/core/hle/kernel/svc')
-rw-r--r-- | src/core/hle/kernel/svc/svc_address_arbiter.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/svc/svc_condition_variable.cpp | 3 | ||||
-rw-r--r-- | src/core/hle/kernel/svc/svc_ipc.cpp | 20 | ||||
-rw-r--r-- | src/core/hle/kernel/svc/svc_resource_limit.cpp | 2 | ||||
-rw-r--r-- | src/core/hle/kernel/svc/svc_synchronization.cpp | 16 | ||||
-rw-r--r-- | src/core/hle/kernel/svc/svc_thread.cpp | 29 |
6 files changed, 58 insertions, 15 deletions
diff --git a/src/core/hle/kernel/svc/svc_address_arbiter.cpp b/src/core/hle/kernel/svc/svc_address_arbiter.cpp index 04cc5ea64..90ee43521 100644 --- a/src/core/hle/kernel/svc/svc_address_arbiter.cpp +++ b/src/core/hle/kernel/svc/svc_address_arbiter.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" @@ -52,7 +53,7 @@ Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_typ if (timeout_ns > 0) { const s64 offset_tick(timeout_ns); if (offset_tick > 0) { - timeout = offset_tick + 2; + timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; if (timeout <= 0) { timeout = std::numeric_limits<s64>::max(); } diff --git a/src/core/hle/kernel/svc/svc_condition_variable.cpp b/src/core/hle/kernel/svc/svc_condition_variable.cpp index ca120d67e..bb678e6c5 100644 --- a/src/core/hle/kernel/svc/svc_condition_variable.cpp +++ b/src/core/hle/kernel/svc/svc_condition_variable.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/core.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_memory_layout.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/kernel.h" @@ -25,7 +26,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u if (timeout_ns > 0) { const s64 offset_tick(timeout_ns); if (offset_tick > 0) { - timeout = offset_tick + 2; + timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; if (timeout <= 0) { timeout = std::numeric_limits<s64>::max(); } diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp index 373ae7c8d..6b5e1cb8d 100644 --- a/src/core/hle/kernel/svc/svc_ipc.cpp +++ b/src/core/hle/kernel/svc/svc_ipc.cpp @@ -5,6 +5,7 @@ #include "common/scratch_buffer.h" #include "core/core.h" #include "core/hle/kernel/k_client_session.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_server_session.h" #include "core/hle/kernel/svc.h" @@ -82,12 +83,29 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad R_TRY(session->SendReply()); } + // Convert the timeout from nanoseconds to ticks. + // NOTE: Nintendo does not use this conversion logic in WaitSynchronization... + s64 timeout; + if (timeout_ns > 0) { + const s64 offset_tick(timeout_ns); + if (offset_tick > 0) { + timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; + if (timeout <= 0) { + timeout = std::numeric_limits<s64>::max(); + } + } else { + timeout = std::numeric_limits<s64>::max(); + } + } else { + timeout = timeout_ns; + } + // Wait for a message. while (true) { // Wait for an object. s32 index; Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), - num_handles, timeout_ns); + num_handles, timeout); if (result == ResultTimedOut) { R_RETURN(result); } diff --git a/src/core/hle/kernel/svc/svc_resource_limit.cpp b/src/core/hle/kernel/svc/svc_resource_limit.cpp index 732bc017e..c8e820b6a 100644 --- a/src/core/hle/kernel/svc/svc_resource_limit.cpp +++ b/src/core/hle/kernel/svc/svc_resource_limit.cpp @@ -21,7 +21,7 @@ Result CreateResourceLimit(Core::System& system, Handle* out_handle) { SCOPE_EXIT({ resource_limit->Close(); }); // Initialize the resource limit. - resource_limit->Initialize(std::addressof(system.CoreTiming())); + resource_limit->Initialize(); // Register the limit. KResourceLimit::Register(kernel, resource_limit); diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp index 366e8ed4a..8ebc1bd1c 100644 --- a/src/core/hle/kernel/svc/svc_synchronization.cpp +++ b/src/core/hle/kernel/svc/svc_synchronization.cpp @@ -4,6 +4,7 @@ #include "common/scope_exit.h" #include "common/scratch_buffer.h" #include "core/core.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_readable_event.h" #include "core/hle/kernel/svc.h" @@ -83,9 +84,20 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha } }); + // Convert the timeout from nanoseconds to ticks. + s64 timeout; + if (timeout_ns > 0) { + u64 ticks = kernel.HardwareTimer().GetTick(); + ticks += timeout_ns; + ticks += 2; + + timeout = ticks; + } else { + timeout = timeout_ns; + } + // Wait on the objects. - Result res = - KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns); + Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout); R_SUCCEED_IF(res == ResultSessionClosed); R_RETURN(res); diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp index 92bcea72b..933b82e30 100644 --- a/src/core/hle/kernel/svc/svc_thread.cpp +++ b/src/core/hle/kernel/svc/svc_thread.cpp @@ -4,6 +4,7 @@ #include "common/scope_exit.h" #include "core/core.h" #include "core/core_timing.h" +#include "core/hle/kernel/k_hardware_timer.h" #include "core/hle/kernel/k_process.h" #include "core/hle/kernel/k_scoped_resource_reservation.h" #include "core/hle/kernel/k_thread.h" @@ -42,9 +43,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); // Reserve a new thread from the process resource limit (waiting up to 100ms). - KScopedResourceReservation thread_reservation( - std::addressof(process), LimitableResource::ThreadCountMax, 1, - system.CoreTiming().GetGlobalTimeNs().count() + 100000000); + KScopedResourceReservation thread_reservation(std::addressof(process), + LimitableResource::ThreadCountMax, 1, + kernel.HardwareTimer().GetTick() + 100000000); R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); // Create the thread. @@ -102,20 +103,31 @@ void ExitThread(Core::System& system) { } /// Sleep the current thread -void SleepThread(Core::System& system, s64 nanoseconds) { +void SleepThread(Core::System& system, s64 ns) { auto& kernel = system.Kernel(); - const auto yield_type = static_cast<Svc::YieldType>(nanoseconds); + const auto yield_type = static_cast<Svc::YieldType>(ns); - LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); + LOG_TRACE(Kernel_SVC, "called nanoseconds={}", ns); // When the input tick is positive, sleep. - if (nanoseconds > 0) { + if (ns > 0) { // Convert the timeout from nanoseconds to ticks. // NOTE: Nintendo does not use this conversion logic in WaitSynchronization... + s64 timeout; + + const s64 offset_tick(ns); + if (offset_tick > 0) { + timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; + if (timeout <= 0) { + timeout = std::numeric_limits<s64>::max(); + } + } else { + timeout = std::numeric_limits<s64>::max(); + } // Sleep. // NOTE: Nintendo does not check the result of this sleep. - static_cast<void>(GetCurrentThread(kernel).Sleep(nanoseconds)); + static_cast<void>(GetCurrentThread(kernel).Sleep(timeout)); } else if (yield_type == Svc::YieldType::WithoutCoreMigration) { KScheduler::YieldWithoutCoreMigration(kernel); } else if (yield_type == Svc::YieldType::WithCoreMigration) { @@ -124,7 +136,6 @@ void SleepThread(Core::System& system, s64 nanoseconds) { KScheduler::YieldToAnyThread(kernel); } else { // Nintendo does nothing at all if an otherwise invalid value is passed. - ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds); } } |