summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel/svc
diff options
context:
space:
mode:
authorGravatar liamwhite2023-08-18 09:12:19 -0400
committerGravatar GitHub2023-08-18 09:12:19 -0400
commit314d3858a1cb6db72ef66ca41dd2cd9061cdbec4 (patch)
tree0de70ba0585b5e3dc68cff10dfd330ce29bbab8e /src/core/hle/kernel/svc
parentMerge pull request #11310 from vonchenplus/vulkan_format (diff)
parentkernel: remove relative task registration (diff)
downloadyuzu-314d3858a1cb6db72ef66ca41dd2cd9061cdbec4.tar.gz
yuzu-314d3858a1cb6db72ef66ca41dd2cd9061cdbec4.tar.xz
yuzu-314d3858a1cb6db72ef66ca41dd2cd9061cdbec4.zip
Merge pull request #11288 from liamwhite/svc-tick
kernel: remove relative task registration
Diffstat (limited to 'src/core/hle/kernel/svc')
-rw-r--r--src/core/hle/kernel/svc/svc_address_arbiter.cpp3
-rw-r--r--src/core/hle/kernel/svc/svc_condition_variable.cpp3
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp20
-rw-r--r--src/core/hle/kernel/svc/svc_resource_limit.cpp2
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp16
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp29
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 @@
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
105void SleepThread(Core::System& system, s64 nanoseconds) { 106void 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