diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_hardware_timer.h | 9 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_resource_limit.cpp | 11 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_resource_limit.h | 3 | ||||
| -rw-r--r-- | src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/kernel.cpp | 2 | ||||
| -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 |
11 files changed, 67 insertions, 33 deletions
diff --git a/src/core/hle/kernel/k_hardware_timer.h b/src/core/hle/kernel/k_hardware_timer.h index 00bef6ea1..27f43cd19 100644 --- a/src/core/hle/kernel/k_hardware_timer.h +++ b/src/core/hle/kernel/k_hardware_timer.h | |||
| @@ -19,13 +19,7 @@ public: | |||
| 19 | void Initialize(); | 19 | void Initialize(); |
| 20 | void Finalize(); | 20 | void Finalize(); |
| 21 | 21 | ||
| 22 | s64 GetCount() const { | 22 | s64 GetTick() const; |
| 23 | return GetTick(); | ||
| 24 | } | ||
| 25 | |||
| 26 | void RegisterTask(KTimerTask* task, s64 time_from_now) { | ||
| 27 | this->RegisterAbsoluteTask(task, GetTick() + time_from_now); | ||
| 28 | } | ||
| 29 | 23 | ||
| 30 | void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) { | 24 | void RegisterAbsoluteTask(KTimerTask* task, s64 task_time) { |
| 31 | KScopedDisableDispatch dd{m_kernel}; | 25 | KScopedDisableDispatch dd{m_kernel}; |
| @@ -42,7 +36,6 @@ private: | |||
| 42 | void EnableInterrupt(s64 wakeup_time); | 36 | void EnableInterrupt(s64 wakeup_time); |
| 43 | void DisableInterrupt(); | 37 | void DisableInterrupt(); |
| 44 | bool GetInterruptEnabled(); | 38 | bool GetInterruptEnabled(); |
| 45 | s64 GetTick() const; | ||
| 46 | void DoTask(); | 39 | void DoTask(); |
| 47 | 40 | ||
| 48 | private: | 41 | private: |
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp index fcee26a29..d8a63aaf8 100644 --- a/src/core/hle/kernel/k_resource_limit.cpp +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -5,6 +5,7 @@ | |||
| 5 | #include "common/overflow.h" | 5 | #include "common/overflow.h" |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/core_timing.h" | 7 | #include "core/core_timing.h" |
| 8 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 8 | #include "core/hle/kernel/k_resource_limit.h" | 9 | #include "core/hle/kernel/k_resource_limit.h" |
| 9 | #include "core/hle/kernel/svc_results.h" | 10 | #include "core/hle/kernel/svc_results.h" |
| 10 | 11 | ||
| @@ -15,9 +16,7 @@ KResourceLimit::KResourceLimit(KernelCore& kernel) | |||
| 15 | : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock{m_kernel}, m_cond_var{m_kernel} {} | 16 | : KAutoObjectWithSlabHeapAndContainer{kernel}, m_lock{m_kernel}, m_cond_var{m_kernel} {} |
| 16 | KResourceLimit::~KResourceLimit() = default; | 17 | KResourceLimit::~KResourceLimit() = default; |
| 17 | 18 | ||
| 18 | void KResourceLimit::Initialize(const Core::Timing::CoreTiming* core_timing) { | 19 | void KResourceLimit::Initialize() {} |
| 19 | m_core_timing = core_timing; | ||
| 20 | } | ||
| 21 | 20 | ||
| 22 | void KResourceLimit::Finalize() {} | 21 | void KResourceLimit::Finalize() {} |
| 23 | 22 | ||
| @@ -86,7 +85,7 @@ Result KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | |||
| 86 | } | 85 | } |
| 87 | 86 | ||
| 88 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { | 87 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { |
| 89 | return Reserve(which, value, m_core_timing->GetGlobalTimeNs().count() + DefaultTimeout); | 88 | return Reserve(which, value, m_kernel.HardwareTimer().GetTick() + DefaultTimeout); |
| 90 | } | 89 | } |
| 91 | 90 | ||
| 92 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | 91 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { |
| @@ -117,7 +116,7 @@ bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | |||
| 117 | } | 116 | } |
| 118 | 117 | ||
| 119 | if (m_current_hints[index] + value <= m_limit_values[index] && | 118 | if (m_current_hints[index] + value <= m_limit_values[index] && |
| 120 | (timeout < 0 || m_core_timing->GetGlobalTimeNs().count() < timeout)) { | 119 | (timeout < 0 || m_kernel.HardwareTimer().GetTick() < timeout)) { |
| 121 | m_waiter_count++; | 120 | m_waiter_count++; |
| 122 | m_cond_var.Wait(std::addressof(m_lock), timeout, false); | 121 | m_cond_var.Wait(std::addressof(m_lock), timeout, false); |
| 123 | m_waiter_count--; | 122 | m_waiter_count--; |
| @@ -154,7 +153,7 @@ void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { | |||
| 154 | 153 | ||
| 155 | KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size) { | 154 | KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size) { |
| 156 | auto* resource_limit = KResourceLimit::Create(system.Kernel()); | 155 | auto* resource_limit = KResourceLimit::Create(system.Kernel()); |
| 157 | resource_limit->Initialize(std::addressof(system.CoreTiming())); | 156 | resource_limit->Initialize(); |
| 158 | 157 | ||
| 159 | // Initialize default resource limit values. | 158 | // Initialize default resource limit values. |
| 160 | // TODO(bunnei): These values are the system defaults, the limits for service processes are | 159 | // TODO(bunnei): These values are the system defaults, the limits for service processes are |
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h index 15e69af56..b733ec8f8 100644 --- a/src/core/hle/kernel/k_resource_limit.h +++ b/src/core/hle/kernel/k_resource_limit.h | |||
| @@ -31,7 +31,7 @@ public: | |||
| 31 | explicit KResourceLimit(KernelCore& kernel); | 31 | explicit KResourceLimit(KernelCore& kernel); |
| 32 | ~KResourceLimit() override; | 32 | ~KResourceLimit() override; |
| 33 | 33 | ||
| 34 | void Initialize(const Core::Timing::CoreTiming* core_timing); | 34 | void Initialize(); |
| 35 | void Finalize() override; | 35 | void Finalize() override; |
| 36 | 36 | ||
| 37 | s64 GetLimitValue(LimitableResource which) const; | 37 | s64 GetLimitValue(LimitableResource which) const; |
| @@ -57,7 +57,6 @@ private: | |||
| 57 | mutable KLightLock m_lock; | 57 | mutable KLightLock m_lock; |
| 58 | s32 m_waiter_count{}; | 58 | s32 m_waiter_count{}; |
| 59 | KLightConditionVariable m_cond_var; | 59 | KLightConditionVariable m_cond_var; |
| 60 | const Core::Timing::CoreTiming* m_core_timing{}; | ||
| 61 | }; | 60 | }; |
| 62 | 61 | ||
| 63 | KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size); | 62 | KResourceLimit* CreateResourceLimitForProcess(Core::System& system, s64 physical_memory_size); |
diff --git a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h index c485022f5..b62415da7 100644 --- a/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h +++ b/src/core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h | |||
| @@ -28,7 +28,7 @@ public: | |||
| 28 | ~KScopedSchedulerLockAndSleep() { | 28 | ~KScopedSchedulerLockAndSleep() { |
| 29 | // Register the sleep. | 29 | // Register the sleep. |
| 30 | if (m_timeout_tick > 0) { | 30 | if (m_timeout_tick > 0) { |
| 31 | m_timer->RegisterTask(m_thread, m_timeout_tick); | 31 | m_timer->RegisterAbsoluteTask(m_thread, m_timeout_tick); |
| 32 | } | 32 | } |
| 33 | 33 | ||
| 34 | // Unlock the scheduler. | 34 | // Unlock the scheduler. |
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index ebe7582c6..a1134b7e2 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -231,7 +231,7 @@ struct KernelCore::Impl { | |||
| 231 | void InitializeSystemResourceLimit(KernelCore& kernel, | 231 | void InitializeSystemResourceLimit(KernelCore& kernel, |
| 232 | const Core::Timing::CoreTiming& core_timing) { | 232 | const Core::Timing::CoreTiming& core_timing) { |
| 233 | system_resource_limit = KResourceLimit::Create(system.Kernel()); | 233 | system_resource_limit = KResourceLimit::Create(system.Kernel()); |
| 234 | system_resource_limit->Initialize(&core_timing); | 234 | system_resource_limit->Initialize(); |
| 235 | KResourceLimit::Register(kernel, system_resource_limit); | 235 | KResourceLimit::Register(kernel, system_resource_limit); |
| 236 | 236 | ||
| 237 | const auto sizes{memory_layout->GetTotalAndKernelMemorySizes()}; | 237 | const auto sizes{memory_layout->GetTotalAndKernelMemorySizes()}; |
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 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 5 | #include "core/hle/kernel/k_memory_layout.h" | 6 | #include "core/hle/kernel/k_memory_layout.h" |
| 6 | #include "core/hle/kernel/k_process.h" | 7 | #include "core/hle/kernel/k_process.h" |
| 7 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/kernel.h" |
| @@ -52,7 +53,7 @@ Result WaitForAddress(Core::System& system, u64 address, ArbitrationType arb_typ | |||
| 52 | if (timeout_ns > 0) { | 53 | if (timeout_ns > 0) { |
| 53 | const s64 offset_tick(timeout_ns); | 54 | const s64 offset_tick(timeout_ns); |
| 54 | if (offset_tick > 0) { | 55 | if (offset_tick > 0) { |
| 55 | timeout = offset_tick + 2; | 56 | timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; |
| 56 | if (timeout <= 0) { | 57 | if (timeout <= 0) { |
| 57 | timeout = std::numeric_limits<s64>::max(); | 58 | timeout = std::numeric_limits<s64>::max(); |
| 58 | } | 59 | } |
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 @@ | |||
| 2 | // SPDX-License-Identifier: GPL-2.0-or-later | 2 | // SPDX-License-Identifier: GPL-2.0-or-later |
| 3 | 3 | ||
| 4 | #include "core/core.h" | 4 | #include "core/core.h" |
| 5 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 5 | #include "core/hle/kernel/k_memory_layout.h" | 6 | #include "core/hle/kernel/k_memory_layout.h" |
| 6 | #include "core/hle/kernel/k_process.h" | 7 | #include "core/hle/kernel/k_process.h" |
| 7 | #include "core/hle/kernel/kernel.h" | 8 | #include "core/hle/kernel/kernel.h" |
| @@ -25,7 +26,7 @@ Result WaitProcessWideKeyAtomic(Core::System& system, u64 address, u64 cv_key, u | |||
| 25 | if (timeout_ns > 0) { | 26 | if (timeout_ns > 0) { |
| 26 | const s64 offset_tick(timeout_ns); | 27 | const s64 offset_tick(timeout_ns); |
| 27 | if (offset_tick > 0) { | 28 | if (offset_tick > 0) { |
| 28 | timeout = offset_tick + 2; | 29 | timeout = system.Kernel().HardwareTimer().GetTick() + offset_tick + 2; |
| 29 | if (timeout <= 0) { | 30 | if (timeout <= 0) { |
| 30 | timeout = std::numeric_limits<s64>::max(); | 31 | timeout = std::numeric_limits<s64>::max(); |
| 31 | } | 32 | } |
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 @@ | |||
| 5 | #include "common/scratch_buffer.h" | 5 | #include "common/scratch_buffer.h" |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/hle/kernel/k_client_session.h" | 7 | #include "core/hle/kernel/k_client_session.h" |
| 8 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 8 | #include "core/hle/kernel/k_process.h" | 9 | #include "core/hle/kernel/k_process.h" |
| 9 | #include "core/hle/kernel/k_server_session.h" | 10 | #include "core/hle/kernel/k_server_session.h" |
| 10 | #include "core/hle/kernel/svc.h" | 11 | #include "core/hle/kernel/svc.h" |
| @@ -82,12 +83,29 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad | |||
| 82 | R_TRY(session->SendReply()); | 83 | R_TRY(session->SendReply()); |
| 83 | } | 84 | } |
| 84 | 85 | ||
| 86 | // Convert the timeout from nanoseconds to ticks. | ||
| 87 | // NOTE: Nintendo does not use this conversion logic in WaitSynchronization... | ||
| 88 | s64 timeout; | ||
| 89 | if (timeout_ns > 0) { | ||
| 90 | const s64 offset_tick(timeout_ns); | ||
| 91 | if (offset_tick > 0) { | ||
| 92 | timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; | ||
| 93 | if (timeout <= 0) { | ||
| 94 | timeout = std::numeric_limits<s64>::max(); | ||
| 95 | } | ||
| 96 | } else { | ||
| 97 | timeout = std::numeric_limits<s64>::max(); | ||
| 98 | } | ||
| 99 | } else { | ||
| 100 | timeout = timeout_ns; | ||
| 101 | } | ||
| 102 | |||
| 85 | // Wait for a message. | 103 | // Wait for a message. |
| 86 | while (true) { | 104 | while (true) { |
| 87 | // Wait for an object. | 105 | // Wait for an object. |
| 88 | s32 index; | 106 | s32 index; |
| 89 | Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), | 107 | Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), |
| 90 | num_handles, timeout_ns); | 108 | num_handles, timeout); |
| 91 | if (result == ResultTimedOut) { | 109 | if (result == ResultTimedOut) { |
| 92 | R_RETURN(result); | 110 | R_RETURN(result); |
| 93 | } | 111 | } |
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) { | |||
| 21 | SCOPE_EXIT({ resource_limit->Close(); }); | 21 | SCOPE_EXIT({ resource_limit->Close(); }); |
| 22 | 22 | ||
| 23 | // Initialize the resource limit. | 23 | // Initialize the resource limit. |
| 24 | resource_limit->Initialize(std::addressof(system.CoreTiming())); | 24 | resource_limit->Initialize(); |
| 25 | 25 | ||
| 26 | // Register the limit. | 26 | // Register the limit. |
| 27 | KResourceLimit::Register(kernel, resource_limit); | 27 | 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 @@ | |||
| 4 | #include "common/scope_exit.h" | 4 | #include "common/scope_exit.h" |
| 5 | #include "common/scratch_buffer.h" | 5 | #include "common/scratch_buffer.h" |
| 6 | #include "core/core.h" | 6 | #include "core/core.h" |
| 7 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 7 | #include "core/hle/kernel/k_process.h" | 8 | #include "core/hle/kernel/k_process.h" |
| 8 | #include "core/hle/kernel/k_readable_event.h" | 9 | #include "core/hle/kernel/k_readable_event.h" |
| 9 | #include "core/hle/kernel/svc.h" | 10 | #include "core/hle/kernel/svc.h" |
| @@ -83,9 +84,20 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha | |||
| 83 | } | 84 | } |
| 84 | }); | 85 | }); |
| 85 | 86 | ||
| 87 | // Convert the timeout from nanoseconds to ticks. | ||
| 88 | s64 timeout; | ||
| 89 | if (timeout_ns > 0) { | ||
| 90 | u64 ticks = kernel.HardwareTimer().GetTick(); | ||
| 91 | ticks += timeout_ns; | ||
| 92 | ticks += 2; | ||
| 93 | |||
| 94 | timeout = ticks; | ||
| 95 | } else { | ||
| 96 | timeout = timeout_ns; | ||
| 97 | } | ||
| 98 | |||
| 86 | // Wait on the objects. | 99 | // Wait on the objects. |
| 87 | Result res = | 100 | Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout); |
| 88 | KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns); | ||
| 89 | 101 | ||
| 90 | R_SUCCEED_IF(res == ResultSessionClosed); | 102 | R_SUCCEED_IF(res == ResultSessionClosed); |
| 91 | R_RETURN(res); | 103 | 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 @@ | |||
| 4 | #include "common/scope_exit.h" | 4 | #include "common/scope_exit.h" |
| 5 | #include "core/core.h" | 5 | #include "core/core.h" |
| 6 | #include "core/core_timing.h" | 6 | #include "core/core_timing.h" |
| 7 | #include "core/hle/kernel/k_hardware_timer.h" | ||
| 7 | #include "core/hle/kernel/k_process.h" | 8 | #include "core/hle/kernel/k_process.h" |
| 8 | #include "core/hle/kernel/k_scoped_resource_reservation.h" | 9 | #include "core/hle/kernel/k_scoped_resource_reservation.h" |
| 9 | #include "core/hle/kernel/k_thread.h" | 10 | #include "core/hle/kernel/k_thread.h" |
| @@ -42,9 +43,9 @@ Result CreateThread(Core::System& system, Handle* out_handle, u64 entry_point, u | |||
| 42 | R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); | 43 | R_UNLESS(process.CheckThreadPriority(priority), ResultInvalidPriority); |
| 43 | 44 | ||
| 44 | // Reserve a new thread from the process resource limit (waiting up to 100ms). | 45 | // Reserve a new thread from the process resource limit (waiting up to 100ms). |
| 45 | KScopedResourceReservation thread_reservation( | 46 | KScopedResourceReservation thread_reservation(std::addressof(process), |
| 46 | std::addressof(process), LimitableResource::ThreadCountMax, 1, | 47 | LimitableResource::ThreadCountMax, 1, |
| 47 | system.CoreTiming().GetGlobalTimeNs().count() + 100000000); | 48 | kernel.HardwareTimer().GetTick() + 100000000); |
| 48 | R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); | 49 | R_UNLESS(thread_reservation.Succeeded(), ResultLimitReached); |
| 49 | 50 | ||
| 50 | // Create the thread. | 51 | // Create the thread. |
| @@ -102,20 +103,31 @@ void ExitThread(Core::System& system) { | |||
| 102 | } | 103 | } |
| 103 | 104 | ||
| 104 | /// Sleep the current thread | 105 | /// Sleep the current thread |
| 105 | void SleepThread(Core::System& system, s64 nanoseconds) { | 106 | void SleepThread(Core::System& system, s64 ns) { |
| 106 | auto& kernel = system.Kernel(); | 107 | auto& kernel = system.Kernel(); |
| 107 | const auto yield_type = static_cast<Svc::YieldType>(nanoseconds); | 108 | const auto yield_type = static_cast<Svc::YieldType>(ns); |
| 108 | 109 | ||
| 109 | LOG_TRACE(Kernel_SVC, "called nanoseconds={}", nanoseconds); | 110 | LOG_TRACE(Kernel_SVC, "called nanoseconds={}", ns); |
| 110 | 111 | ||
| 111 | // When the input tick is positive, sleep. | 112 | // When the input tick is positive, sleep. |
| 112 | if (nanoseconds > 0) { | 113 | if (ns > 0) { |
| 113 | // Convert the timeout from nanoseconds to ticks. | 114 | // Convert the timeout from nanoseconds to ticks. |
| 114 | // NOTE: Nintendo does not use this conversion logic in WaitSynchronization... | 115 | // NOTE: Nintendo does not use this conversion logic in WaitSynchronization... |
| 116 | s64 timeout; | ||
| 117 | |||
| 118 | const s64 offset_tick(ns); | ||
| 119 | if (offset_tick > 0) { | ||
| 120 | timeout = kernel.HardwareTimer().GetTick() + offset_tick + 2; | ||
| 121 | if (timeout <= 0) { | ||
| 122 | timeout = std::numeric_limits<s64>::max(); | ||
| 123 | } | ||
| 124 | } else { | ||
| 125 | timeout = std::numeric_limits<s64>::max(); | ||
| 126 | } | ||
| 115 | 127 | ||
| 116 | // Sleep. | 128 | // Sleep. |
| 117 | // NOTE: Nintendo does not check the result of this sleep. | 129 | // NOTE: Nintendo does not check the result of this sleep. |
| 118 | static_cast<void>(GetCurrentThread(kernel).Sleep(nanoseconds)); | 130 | static_cast<void>(GetCurrentThread(kernel).Sleep(timeout)); |
| 119 | } else if (yield_type == Svc::YieldType::WithoutCoreMigration) { | 131 | } else if (yield_type == Svc::YieldType::WithoutCoreMigration) { |
| 120 | KScheduler::YieldWithoutCoreMigration(kernel); | 132 | KScheduler::YieldWithoutCoreMigration(kernel); |
| 121 | } else if (yield_type == Svc::YieldType::WithCoreMigration) { | 133 | } else if (yield_type == Svc::YieldType::WithCoreMigration) { |
| @@ -124,7 +136,6 @@ void SleepThread(Core::System& system, s64 nanoseconds) { | |||
| 124 | KScheduler::YieldToAnyThread(kernel); | 136 | KScheduler::YieldToAnyThread(kernel); |
| 125 | } else { | 137 | } else { |
| 126 | // Nintendo does nothing at all if an otherwise invalid value is passed. | 138 | // Nintendo does nothing at all if an otherwise invalid value is passed. |
| 127 | ASSERT_MSG(false, "Unimplemented sleep yield type '{:016X}'!", nanoseconds); | ||
| 128 | } | 139 | } |
| 129 | } | 140 | } |
| 130 | 141 | ||