summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2023-06-22 21:53:07 -0700
committerGravatar GitHub2023-06-22 21:53:07 -0700
commit2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8 (patch)
treed82f2cf4f7a5e9773616846c095a941b282a84f6 /src/core/hle/kernel
parentMerge pull request #10806 from liamwhite/worst-fs-implementation-ever (diff)
parentRemove memory allocations in some hot paths (diff)
downloadyuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.tar.gz
yuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.tar.xz
yuzu-2fc5dedf6996d4a5c93ddf1ccd67a6963e4827e8.zip
Merge pull request #10457 from Kelebek1/optimise
Remove memory allocations in some hot paths
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_synchronization_object.cpp3
-rw-r--r--src/core/hle/kernel/k_thread.cpp8
-rw-r--r--src/core/hle/kernel/k_thread.h3
-rw-r--r--src/core/hle/kernel/svc/svc_ipc.cpp7
-rw-r--r--src/core/hle/kernel/svc/svc_synchronization.cpp10
-rw-r--r--src/core/hle/kernel/svc/svc_thread.cpp2
6 files changed, 17 insertions, 16 deletions
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp
index b7da3eee7..3e5b735b1 100644
--- a/src/core/hle/kernel/k_synchronization_object.cpp
+++ b/src/core/hle/kernel/k_synchronization_object.cpp
@@ -3,6 +3,7 @@
3 3
4#include "common/assert.h" 4#include "common/assert.h"
5#include "common/common_types.h" 5#include "common/common_types.h"
6#include "common/scratch_buffer.h"
6#include "core/hle/kernel/k_scheduler.h" 7#include "core/hle/kernel/k_scheduler.h"
7#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" 8#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h"
8#include "core/hle/kernel/k_synchronization_object.h" 9#include "core/hle/kernel/k_synchronization_object.h"
@@ -75,7 +76,7 @@ Result KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
75 KSynchronizationObject** objects, const s32 num_objects, 76 KSynchronizationObject** objects, const s32 num_objects,
76 s64 timeout) { 77 s64 timeout) {
77 // Allocate space on stack for thread nodes. 78 // Allocate space on stack for thread nodes.
78 std::vector<ThreadListNode> thread_nodes(num_objects); 79 std::array<ThreadListNode, Svc::ArgumentHandleCountMax> thread_nodes;
79 80
80 // Prepare for wait. 81 // Prepare for wait.
81 KThread* thread = GetCurrentThreadPointer(kernel); 82 KThread* thread = GetCurrentThreadPointer(kernel);
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp
index 908811e2c..adb6ec581 100644
--- a/src/core/hle/kernel/k_thread.cpp
+++ b/src/core/hle/kernel/k_thread.cpp
@@ -909,7 +909,7 @@ Result KThread::SetActivity(Svc::ThreadActivity activity) {
909 R_SUCCEED(); 909 R_SUCCEED();
910} 910}
911 911
912Result KThread::GetThreadContext3(std::vector<u8>& out) { 912Result KThread::GetThreadContext3(Common::ScratchBuffer<u8>& out) {
913 // Lock ourselves. 913 // Lock ourselves.
914 KScopedLightLock lk{m_activity_pause_lock}; 914 KScopedLightLock lk{m_activity_pause_lock};
915 915
@@ -927,15 +927,13 @@ Result KThread::GetThreadContext3(std::vector<u8>& out) {
927 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. 927 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
928 auto context = GetContext64(); 928 auto context = GetContext64();
929 context.pstate &= 0xFF0FFE20; 929 context.pstate &= 0xFF0FFE20;
930 930 out.resize_destructive(sizeof(context));
931 out.resize(sizeof(context));
932 std::memcpy(out.data(), std::addressof(context), sizeof(context)); 931 std::memcpy(out.data(), std::addressof(context), sizeof(context));
933 } else { 932 } else {
934 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits. 933 // Mask away mode bits, interrupt bits, IL bit, and other reserved bits.
935 auto context = GetContext32(); 934 auto context = GetContext32();
936 context.cpsr &= 0xFF0FFE20; 935 context.cpsr &= 0xFF0FFE20;
937 936 out.resize_destructive(sizeof(context));
938 out.resize(sizeof(context));
939 std::memcpy(out.data(), std::addressof(context), sizeof(context)); 937 std::memcpy(out.data(), std::addressof(context), sizeof(context));
940 } 938 }
941 } 939 }
diff --git a/src/core/hle/kernel/k_thread.h b/src/core/hle/kernel/k_thread.h
index 37fe5db77..dd662b3f8 100644
--- a/src/core/hle/kernel/k_thread.h
+++ b/src/core/hle/kernel/k_thread.h
@@ -15,6 +15,7 @@
15#include "common/intrusive_list.h" 15#include "common/intrusive_list.h"
16 16
17#include "common/intrusive_red_black_tree.h" 17#include "common/intrusive_red_black_tree.h"
18#include "common/scratch_buffer.h"
18#include "common/spin_lock.h" 19#include "common/spin_lock.h"
19#include "core/arm/arm_interface.h" 20#include "core/arm/arm_interface.h"
20#include "core/hle/kernel/k_affinity_mask.h" 21#include "core/hle/kernel/k_affinity_mask.h"
@@ -567,7 +568,7 @@ public:
567 568
568 void RemoveWaiter(KThread* thread); 569 void RemoveWaiter(KThread* thread);
569 570
570 Result GetThreadContext3(std::vector<u8>& out); 571 Result GetThreadContext3(Common::ScratchBuffer<u8>& out);
571 572
572 KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) { 573 KThread* RemoveUserWaiterByKey(bool* out_has_waiters, KProcessAddress key) {
573 return this->RemoveWaiterByKey(out_has_waiters, key, false); 574 return this->RemoveWaiterByKey(out_has_waiters, key, false);
diff --git a/src/core/hle/kernel/svc/svc_ipc.cpp b/src/core/hle/kernel/svc/svc_ipc.cpp
index ea03068aa..60247df2e 100644
--- a/src/core/hle/kernel/svc/svc_ipc.cpp
+++ b/src/core/hle/kernel/svc/svc_ipc.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 "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "common/scratch_buffer.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/hle/kernel/k_client_session.h" 7#include "core/hle/kernel/k_client_session.h"
7#include "core/hle/kernel/k_process.h" 8#include "core/hle/kernel/k_process.h"
@@ -45,11 +46,11 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
45 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)), 46 handles_addr, static_cast<u64>(sizeof(Handle) * num_handles)),
46 ResultInvalidPointer); 47 ResultInvalidPointer);
47 48
48 std::vector<Handle> handles(num_handles); 49 std::array<Handle, Svc::ArgumentHandleCountMax> handles;
49 GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles); 50 GetCurrentMemory(kernel).ReadBlock(handles_addr, handles.data(), sizeof(Handle) * num_handles);
50 51
51 // Convert handle list to object table. 52 // Convert handle list to object table.
52 std::vector<KSynchronizationObject*> objs(num_handles); 53 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
53 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(), 54 R_UNLESS(handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles.data(),
54 num_handles), 55 num_handles),
55 ResultInvalidHandle); 56 ResultInvalidHandle);
@@ -80,7 +81,7 @@ Result ReplyAndReceive(Core::System& system, s32* out_index, uint64_t handles_ad
80 // Wait for an object. 81 // Wait for an object.
81 s32 index; 82 s32 index;
82 Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(), 83 Result result = KSynchronizationObject::Wait(kernel, std::addressof(index), objs.data(),
83 static_cast<s32>(objs.size()), timeout_ns); 84 num_handles, timeout_ns);
84 if (result == ResultTimedOut) { 85 if (result == ResultTimedOut) {
85 R_RETURN(result); 86 R_RETURN(result);
86 } 87 }
diff --git a/src/core/hle/kernel/svc/svc_synchronization.cpp b/src/core/hle/kernel/svc/svc_synchronization.cpp
index 04d65f0bd..53df5bcd8 100644
--- a/src/core/hle/kernel/svc/svc_synchronization.cpp
+++ b/src/core/hle/kernel/svc/svc_synchronization.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 "common/scope_exit.h" 4#include "common/scope_exit.h"
5#include "common/scratch_buffer.h"
5#include "core/core.h" 6#include "core/core.h"
6#include "core/hle/kernel/k_process.h" 7#include "core/hle/kernel/k_process.h"
7#include "core/hle/kernel/k_readable_event.h" 8#include "core/hle/kernel/k_readable_event.h"
@@ -54,7 +55,7 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
54 // Get the synchronization context. 55 // Get the synchronization context.
55 auto& kernel = system.Kernel(); 56 auto& kernel = system.Kernel();
56 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable(); 57 auto& handle_table = GetCurrentProcess(kernel).GetHandleTable();
57 std::vector<KSynchronizationObject*> objs(num_handles); 58 std::array<KSynchronizationObject*, Svc::ArgumentHandleCountMax> objs;
58 59
59 // Copy user handles. 60 // Copy user handles.
60 if (num_handles > 0) { 61 if (num_handles > 0) {
@@ -72,8 +73,8 @@ static Result WaitSynchronization(Core::System& system, int32_t* out_index, cons
72 }); 73 });
73 74
74 // Wait on the objects. 75 // Wait on the objects.
75 Result res = KSynchronizationObject::Wait(kernel, out_index, objs.data(), 76 Result res =
76 static_cast<s32>(objs.size()), timeout_ns); 77 KSynchronizationObject::Wait(kernel, out_index, objs.data(), num_handles, timeout_ns);
77 78
78 R_SUCCEED_IF(res == ResultSessionClosed); 79 R_SUCCEED_IF(res == ResultSessionClosed);
79 R_RETURN(res); 80 R_RETURN(res);
@@ -87,8 +88,7 @@ Result WaitSynchronization(Core::System& system, int32_t* out_index, u64 user_ha
87 88
88 // Ensure number of handles is valid. 89 // Ensure number of handles is valid.
89 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange); 90 R_UNLESS(0 <= num_handles && num_handles <= Svc::ArgumentHandleCountMax, ResultOutOfRange);
90 91 std::array<Handle, Svc::ArgumentHandleCountMax> handles;
91 std::vector<Handle> handles(num_handles);
92 if (num_handles > 0) { 92 if (num_handles > 0) {
93 GetCurrentMemory(system.Kernel()) 93 GetCurrentMemory(system.Kernel())
94 .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle)); 94 .ReadBlock(user_handles, handles.data(), num_handles * sizeof(Handle));
diff --git a/src/core/hle/kernel/svc/svc_thread.cpp b/src/core/hle/kernel/svc/svc_thread.cpp
index 37b54079c..36b94e6bf 100644
--- a/src/core/hle/kernel/svc/svc_thread.cpp
+++ b/src/core/hle/kernel/svc/svc_thread.cpp
@@ -174,7 +174,7 @@ Result GetThreadContext3(Core::System& system, u64 out_context, Handle thread_ha
174 } 174 }
175 175
176 // Get the thread context. 176 // Get the thread context.
177 std::vector<u8> context; 177 static thread_local Common::ScratchBuffer<u8> context;
178 R_TRY(thread->GetThreadContext3(context)); 178 R_TRY(thread->GetThreadContext3(context));
179 179
180 // Copy the thread context to user space. 180 // Copy the thread context to user space.