diff options
Diffstat (limited to 'src')
21 files changed, 386 insertions, 240 deletions
diff --git a/src/audio_core/command_generator.cpp b/src/audio_core/command_generator.cpp index a4a9a757d..5b1065520 100644 --- a/src/audio_core/command_generator.cpp +++ b/src/audio_core/command_generator.cpp | |||
| @@ -383,11 +383,14 @@ void CommandGenerator::GenerateI3dl2ReverbEffectCommand(s32 mix_buffer_offset, E | |||
| 383 | const auto channel_count = params.channel_count; | 383 | const auto channel_count = params.channel_count; |
| 384 | for (s32 i = 0; i < channel_count; i++) { | 384 | for (s32 i = 0; i < channel_count; i++) { |
| 385 | // TODO(ogniK): Actually implement reverb | 385 | // TODO(ogniK): Actually implement reverb |
| 386 | /* | ||
| 386 | if (params.input[i] != params.output[i]) { | 387 | if (params.input[i] != params.output[i]) { |
| 387 | const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); | 388 | const auto* input = GetMixBuffer(mix_buffer_offset + params.input[i]); |
| 388 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); | 389 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); |
| 389 | ApplyMix<1>(output, input, 32768, worker_params.sample_count); | 390 | ApplyMix<1>(output, input, 32768, worker_params.sample_count); |
| 390 | } | 391 | }*/ |
| 392 | auto* output = GetMixBuffer(mix_buffer_offset + params.output[i]); | ||
| 393 | std::memset(output, 0, worker_params.sample_count * sizeof(s32)); | ||
| 391 | } | 394 | } |
| 392 | } | 395 | } |
| 393 | 396 | ||
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 397cc028f..0ee02c81d 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt | |||
| @@ -160,9 +160,12 @@ add_library(core STATIC | |||
| 160 | hle/kernel/k_affinity_mask.h | 160 | hle/kernel/k_affinity_mask.h |
| 161 | hle/kernel/k_condition_variable.cpp | 161 | hle/kernel/k_condition_variable.cpp |
| 162 | hle/kernel/k_condition_variable.h | 162 | hle/kernel/k_condition_variable.h |
| 163 | hle/kernel/k_light_condition_variable.h | ||
| 163 | hle/kernel/k_light_lock.cpp | 164 | hle/kernel/k_light_lock.cpp |
| 164 | hle/kernel/k_light_lock.h | 165 | hle/kernel/k_light_lock.h |
| 165 | hle/kernel/k_priority_queue.h | 166 | hle/kernel/k_priority_queue.h |
| 167 | hle/kernel/k_resource_limit.cpp | ||
| 168 | hle/kernel/k_resource_limit.h | ||
| 166 | hle/kernel/k_scheduler.cpp | 169 | hle/kernel/k_scheduler.cpp |
| 167 | hle/kernel/k_scheduler.h | 170 | hle/kernel/k_scheduler.h |
| 168 | hle/kernel/k_scheduler_lock.h | 171 | hle/kernel/k_scheduler_lock.h |
| @@ -203,8 +206,6 @@ add_library(core STATIC | |||
| 203 | hle/kernel/process_capability.h | 206 | hle/kernel/process_capability.h |
| 204 | hle/kernel/readable_event.cpp | 207 | hle/kernel/readable_event.cpp |
| 205 | hle/kernel/readable_event.h | 208 | hle/kernel/readable_event.h |
| 206 | hle/kernel/resource_limit.cpp | ||
| 207 | hle/kernel/resource_limit.h | ||
| 208 | hle/kernel/server_port.cpp | 209 | hle/kernel/server_port.cpp |
| 209 | hle/kernel/server_port.h | 210 | hle/kernel/server_port.h |
| 210 | hle/kernel/server_session.cpp | 211 | hle/kernel/server_session.cpp |
diff --git a/src/core/crypto/key_manager.cpp b/src/core/crypto/key_manager.cpp index cebe2ce37..ad116dcc0 100644 --- a/src/core/crypto/key_manager.cpp +++ b/src/core/crypto/key_manager.cpp | |||
| @@ -568,6 +568,11 @@ KeyManager::KeyManager() { | |||
| 568 | // Initialize keys | 568 | // Initialize keys |
| 569 | const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); | 569 | const std::string hactool_keys_dir = Common::FS::GetHactoolConfigurationPath(); |
| 570 | const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); | 570 | const std::string yuzu_keys_dir = Common::FS::GetUserPath(Common::FS::UserPath::KeysDir); |
| 571 | |||
| 572 | if (!Common::FS::Exists(yuzu_keys_dir)) { | ||
| 573 | Common::FS::CreateDir(yuzu_keys_dir); | ||
| 574 | } | ||
| 575 | |||
| 571 | if (Settings::values.use_dev_keys) { | 576 | if (Settings::values.use_dev_keys) { |
| 572 | dev_mode = true; | 577 | dev_mode = true; |
| 573 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); | 578 | AttemptLoadKeyFile(yuzu_keys_dir, hactool_keys_dir, "dev.keys", false); |
diff --git a/src/core/hle/kernel/k_affinity_mask.h b/src/core/hle/kernel/k_affinity_mask.h index dd73781cd..b906895fc 100644 --- a/src/core/hle/kernel/k_affinity_mask.h +++ b/src/core/hle/kernel/k_affinity_mask.h | |||
| @@ -27,7 +27,7 @@ public: | |||
| 27 | } | 27 | } |
| 28 | 28 | ||
| 29 | [[nodiscard]] constexpr bool GetAffinity(s32 core) const { | 29 | [[nodiscard]] constexpr bool GetAffinity(s32 core) const { |
| 30 | return this->mask & GetCoreBit(core); | 30 | return (this->mask & GetCoreBit(core)) != 0; |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | constexpr void SetAffinity(s32 core, bool set) { | 33 | constexpr void SetAffinity(s32 core, bool set) { |
diff --git a/src/core/hle/kernel/k_light_condition_variable.h b/src/core/hle/kernel/k_light_condition_variable.h new file mode 100644 index 000000000..362d0db28 --- /dev/null +++ b/src/core/hle/kernel/k_light_condition_variable.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/kernel/k_scheduler.h" | ||
| 12 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | ||
| 13 | #include "core/hle/kernel/k_thread_queue.h" | ||
| 14 | #include "core/hle/kernel/time_manager.h" | ||
| 15 | |||
| 16 | namespace Kernel { | ||
| 17 | class KernelCore; | ||
| 18 | |||
| 19 | class KLightConditionVariable { | ||
| 20 | public: | ||
| 21 | explicit KLightConditionVariable(KernelCore& kernel) : thread_queue(kernel), kernel(kernel) {} | ||
| 22 | |||
| 23 | void Wait(KLightLock* lock, s64 timeout = -1) { | ||
| 24 | WaitImpl(lock, timeout); | ||
| 25 | lock->Lock(); | ||
| 26 | } | ||
| 27 | |||
| 28 | void Broadcast() { | ||
| 29 | KScopedSchedulerLock lk{kernel}; | ||
| 30 | while (thread_queue.WakeupFrontThread() != nullptr) { | ||
| 31 | // We want to signal all threads, and so should continue waking up until there's nothing | ||
| 32 | // to wake. | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | private: | ||
| 37 | void WaitImpl(KLightLock* lock, s64 timeout) { | ||
| 38 | KThread* owner = GetCurrentThreadPointer(kernel); | ||
| 39 | |||
| 40 | // Sleep the thread. | ||
| 41 | { | ||
| 42 | KScopedSchedulerLockAndSleep lk(kernel, owner, timeout); | ||
| 43 | lock->Unlock(); | ||
| 44 | |||
| 45 | if (!thread_queue.SleepThread(owner)) { | ||
| 46 | lk.CancelSleep(); | ||
| 47 | return; | ||
| 48 | } | ||
| 49 | } | ||
| 50 | |||
| 51 | // Cancel the task that the sleep setup. | ||
| 52 | kernel.TimeManager().UnscheduleTimeEvent(owner); | ||
| 53 | } | ||
| 54 | KThreadQueue thread_queue; | ||
| 55 | KernelCore& kernel; | ||
| 56 | }; | ||
| 57 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_resource_limit.cpp b/src/core/hle/kernel/k_resource_limit.cpp new file mode 100644 index 000000000..ab2ab683f --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.cpp | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #include "common/assert.h" | ||
| 9 | #include "core/core.h" | ||
| 10 | #include "core/core_timing.h" | ||
| 11 | #include "core/core_timing_util.h" | ||
| 12 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 13 | #include "core/hle/kernel/svc_results.h" | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | constexpr s64 DefaultTimeout = 10000000000; // 10 seconds | ||
| 17 | |||
| 18 | KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system) | ||
| 19 | : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {} | ||
| 20 | KResourceLimit::~KResourceLimit() = default; | ||
| 21 | |||
| 22 | s64 KResourceLimit::GetLimitValue(LimitableResource which) const { | ||
| 23 | const auto index = static_cast<std::size_t>(which); | ||
| 24 | s64 value{}; | ||
| 25 | { | ||
| 26 | KScopedLightLock lk{lock}; | ||
| 27 | value = limit_values[index]; | ||
| 28 | ASSERT(value >= 0); | ||
| 29 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 30 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 31 | } | ||
| 32 | return value; | ||
| 33 | } | ||
| 34 | |||
| 35 | s64 KResourceLimit::GetCurrentValue(LimitableResource which) const { | ||
| 36 | const auto index = static_cast<std::size_t>(which); | ||
| 37 | s64 value{}; | ||
| 38 | { | ||
| 39 | KScopedLightLock lk{lock}; | ||
| 40 | value = current_values[index]; | ||
| 41 | ASSERT(value >= 0); | ||
| 42 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 43 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 44 | } | ||
| 45 | return value; | ||
| 46 | } | ||
| 47 | |||
| 48 | s64 KResourceLimit::GetPeakValue(LimitableResource which) const { | ||
| 49 | const auto index = static_cast<std::size_t>(which); | ||
| 50 | s64 value{}; | ||
| 51 | { | ||
| 52 | KScopedLightLock lk{lock}; | ||
| 53 | value = peak_values[index]; | ||
| 54 | ASSERT(value >= 0); | ||
| 55 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 56 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 57 | } | ||
| 58 | return value; | ||
| 59 | } | ||
| 60 | |||
| 61 | s64 KResourceLimit::GetFreeValue(LimitableResource which) const { | ||
| 62 | const auto index = static_cast<std::size_t>(which); | ||
| 63 | s64 value{}; | ||
| 64 | { | ||
| 65 | KScopedLightLock lk(lock); | ||
| 66 | ASSERT(current_values[index] >= 0); | ||
| 67 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 68 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 69 | value = limit_values[index] - current_values[index]; | ||
| 70 | } | ||
| 71 | |||
| 72 | return value; | ||
| 73 | } | ||
| 74 | |||
| 75 | ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { | ||
| 76 | const auto index = static_cast<std::size_t>(which); | ||
| 77 | KScopedLightLock lk(lock); | ||
| 78 | R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState); | ||
| 79 | |||
| 80 | limit_values[index] = value; | ||
| 81 | |||
| 82 | return RESULT_SUCCESS; | ||
| 83 | } | ||
| 84 | |||
| 85 | bool KResourceLimit::Reserve(LimitableResource which, s64 value) { | ||
| 86 | return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout); | ||
| 87 | } | ||
| 88 | |||
| 89 | bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { | ||
| 90 | ASSERT(value >= 0); | ||
| 91 | const auto index = static_cast<std::size_t>(which); | ||
| 92 | KScopedLightLock lk(lock); | ||
| 93 | |||
| 94 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 95 | if (current_hints[index] >= limit_values[index]) { | ||
| 96 | return false; | ||
| 97 | } | ||
| 98 | |||
| 99 | // Loop until we reserve or run out of time. | ||
| 100 | while (true) { | ||
| 101 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 102 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 103 | |||
| 104 | // If we would overflow, don't allow to succeed. | ||
| 105 | if (current_values[index] + value <= current_values[index]) { | ||
| 106 | break; | ||
| 107 | } | ||
| 108 | |||
| 109 | if (current_values[index] + value <= limit_values[index]) { | ||
| 110 | current_values[index] += value; | ||
| 111 | current_hints[index] += value; | ||
| 112 | peak_values[index] = std::max(peak_values[index], current_values[index]); | ||
| 113 | return true; | ||
| 114 | } | ||
| 115 | |||
| 116 | if (current_hints[index] + value <= limit_values[index] && | ||
| 117 | (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) { | ||
| 118 | waiter_count++; | ||
| 119 | cond_var.Wait(&lock, timeout); | ||
| 120 | waiter_count--; | ||
| 121 | } else { | ||
| 122 | break; | ||
| 123 | } | ||
| 124 | } | ||
| 125 | |||
| 126 | return false; | ||
| 127 | } | ||
| 128 | |||
| 129 | void KResourceLimit::Release(LimitableResource which, s64 value) { | ||
| 130 | Release(which, value, value); | ||
| 131 | } | ||
| 132 | |||
| 133 | void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { | ||
| 134 | ASSERT(value >= 0); | ||
| 135 | ASSERT(hint >= 0); | ||
| 136 | |||
| 137 | const auto index = static_cast<std::size_t>(which); | ||
| 138 | KScopedLightLock lk(lock); | ||
| 139 | ASSERT(current_values[index] <= limit_values[index]); | ||
| 140 | ASSERT(current_hints[index] <= current_values[index]); | ||
| 141 | ASSERT(value <= current_values[index]); | ||
| 142 | ASSERT(hint <= current_hints[index]); | ||
| 143 | |||
| 144 | current_values[index] -= value; | ||
| 145 | current_hints[index] -= hint; | ||
| 146 | |||
| 147 | if (waiter_count != 0) { | ||
| 148 | cond_var.Broadcast(); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_resource_limit.h b/src/core/hle/kernel/k_resource_limit.h new file mode 100644 index 000000000..58ae456f1 --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.h | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | // Copyright 2020 yuzu Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | // This file references various implementation details from Atmosphere, an open-source firmware for | ||
| 6 | // the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. | ||
| 7 | |||
| 8 | #pragma once | ||
| 9 | |||
| 10 | #include <array> | ||
| 11 | #include "common/common_types.h" | ||
| 12 | #include "core/hle/kernel/k_light_condition_variable.h" | ||
| 13 | #include "core/hle/kernel/k_light_lock.h" | ||
| 14 | #include "core/hle/kernel/object.h" | ||
| 15 | |||
| 16 | union ResultCode; | ||
| 17 | |||
| 18 | namespace Core { | ||
| 19 | class System; | ||
| 20 | } | ||
| 21 | |||
| 22 | namespace Kernel { | ||
| 23 | class KernelCore; | ||
| 24 | enum class LimitableResource : u32 { | ||
| 25 | PhysicalMemory = 0, | ||
| 26 | Threads = 1, | ||
| 27 | Events = 2, | ||
| 28 | TransferMemory = 3, | ||
| 29 | Sessions = 4, | ||
| 30 | |||
| 31 | Count, | ||
| 32 | }; | ||
| 33 | |||
| 34 | constexpr bool IsValidResourceType(LimitableResource type) { | ||
| 35 | return type < LimitableResource::Count; | ||
| 36 | } | ||
| 37 | |||
| 38 | class KResourceLimit final : public Object { | ||
| 39 | public: | ||
| 40 | explicit KResourceLimit(KernelCore& kernel, Core::System& system); | ||
| 41 | ~KResourceLimit(); | ||
| 42 | |||
| 43 | s64 GetLimitValue(LimitableResource which) const; | ||
| 44 | s64 GetCurrentValue(LimitableResource which) const; | ||
| 45 | s64 GetPeakValue(LimitableResource which) const; | ||
| 46 | s64 GetFreeValue(LimitableResource which) const; | ||
| 47 | |||
| 48 | ResultCode SetLimitValue(LimitableResource which, s64 value); | ||
| 49 | |||
| 50 | bool Reserve(LimitableResource which, s64 value); | ||
| 51 | bool Reserve(LimitableResource which, s64 value, s64 timeout); | ||
| 52 | void Release(LimitableResource which, s64 value); | ||
| 53 | void Release(LimitableResource which, s64 value, s64 hint); | ||
| 54 | |||
| 55 | std::string GetTypeName() const override { | ||
| 56 | return "KResourceLimit"; | ||
| 57 | } | ||
| 58 | std::string GetName() const override { | ||
| 59 | return GetTypeName(); | ||
| 60 | } | ||
| 61 | |||
| 62 | static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||
| 63 | HandleType GetHandleType() const override { | ||
| 64 | return HANDLE_TYPE; | ||
| 65 | } | ||
| 66 | |||
| 67 | virtual void Finalize() override {} | ||
| 68 | |||
| 69 | private: | ||
| 70 | using ResourceArray = std::array<s64, static_cast<std::size_t>(LimitableResource::Count)>; | ||
| 71 | ResourceArray limit_values{}; | ||
| 72 | ResourceArray current_values{}; | ||
| 73 | ResourceArray current_hints{}; | ||
| 74 | ResourceArray peak_values{}; | ||
| 75 | mutable KLightLock lock; | ||
| 76 | s32 waiter_count{}; | ||
| 77 | KLightConditionVariable cond_var; | ||
| 78 | KernelCore& kernel; | ||
| 79 | Core::System& system; | ||
| 80 | }; | ||
| 81 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index aa100e139..b59259c4f 100644 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp | |||
| @@ -21,6 +21,7 @@ | |||
| 21 | #include "core/hle/kernel/errors.h" | 21 | #include "core/hle/kernel/errors.h" |
| 22 | #include "core/hle/kernel/handle_table.h" | 22 | #include "core/hle/kernel/handle_table.h" |
| 23 | #include "core/hle/kernel/k_condition_variable.h" | 23 | #include "core/hle/kernel/k_condition_variable.h" |
| 24 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 24 | #include "core/hle/kernel/k_scheduler.h" | 25 | #include "core/hle/kernel/k_scheduler.h" |
| 25 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 26 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 26 | #include "core/hle/kernel/k_thread.h" | 27 | #include "core/hle/kernel/k_thread.h" |
| @@ -29,7 +30,6 @@ | |||
| 29 | #include "core/hle/kernel/memory/memory_layout.h" | 30 | #include "core/hle/kernel/memory/memory_layout.h" |
| 30 | #include "core/hle/kernel/object.h" | 31 | #include "core/hle/kernel/object.h" |
| 31 | #include "core/hle/kernel/process.h" | 32 | #include "core/hle/kernel/process.h" |
| 32 | #include "core/hle/kernel/resource_limit.h" | ||
| 33 | #include "core/hle/kernel/svc_results.h" | 33 | #include "core/hle/kernel/svc_results.h" |
| 34 | #include "core/hle/kernel/time_manager.h" | 34 | #include "core/hle/kernel/time_manager.h" |
| 35 | #include "core/hle/result.h" | 35 | #include "core/hle/result.h" |
| @@ -247,7 +247,7 @@ void KThread::Finalize() { | |||
| 247 | // Decrement the parent process's thread count. | 247 | // Decrement the parent process's thread count. |
| 248 | if (parent != nullptr) { | 248 | if (parent != nullptr) { |
| 249 | parent->DecrementThreadCount(); | 249 | parent->DecrementThreadCount(); |
| 250 | parent->GetResourceLimit()->Release(ResourceType::Threads, 1); | 250 | parent->GetResourceLimit()->Release(LimitableResource::Threads, 1); |
| 251 | } | 251 | } |
| 252 | } | 252 | } |
| 253 | 253 | ||
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index df309d523..b20c2d13a 100644 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #include "core/hle/kernel/client_port.h" | 28 | #include "core/hle/kernel/client_port.h" |
| 29 | #include "core/hle/kernel/errors.h" | 29 | #include "core/hle/kernel/errors.h" |
| 30 | #include "core/hle/kernel/handle_table.h" | 30 | #include "core/hle/kernel/handle_table.h" |
| 31 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 31 | #include "core/hle/kernel/k_scheduler.h" | 32 | #include "core/hle/kernel/k_scheduler.h" |
| 32 | #include "core/hle/kernel/k_thread.h" | 33 | #include "core/hle/kernel/k_thread.h" |
| 33 | #include "core/hle/kernel/kernel.h" | 34 | #include "core/hle/kernel/kernel.h" |
| @@ -36,7 +37,6 @@ | |||
| 36 | #include "core/hle/kernel/memory/slab_heap.h" | 37 | #include "core/hle/kernel/memory/slab_heap.h" |
| 37 | #include "core/hle/kernel/physical_core.h" | 38 | #include "core/hle/kernel/physical_core.h" |
| 38 | #include "core/hle/kernel/process.h" | 39 | #include "core/hle/kernel/process.h" |
| 39 | #include "core/hle/kernel/resource_limit.h" | ||
| 40 | #include "core/hle/kernel/service_thread.h" | 40 | #include "core/hle/kernel/service_thread.h" |
| 41 | #include "core/hle/kernel/shared_memory.h" | 41 | #include "core/hle/kernel/shared_memory.h" |
| 42 | #include "core/hle/kernel/time_manager.h" | 42 | #include "core/hle/kernel/time_manager.h" |
| @@ -66,7 +66,7 @@ struct KernelCore::Impl { | |||
| 66 | is_phantom_mode_for_singlecore = false; | 66 | is_phantom_mode_for_singlecore = false; |
| 67 | 67 | ||
| 68 | InitializePhysicalCores(); | 68 | InitializePhysicalCores(); |
| 69 | InitializeSystemResourceLimit(kernel); | 69 | InitializeSystemResourceLimit(kernel, system); |
| 70 | InitializeMemoryLayout(); | 70 | InitializeMemoryLayout(); |
| 71 | InitializePreemption(kernel); | 71 | InitializePreemption(kernel); |
| 72 | InitializeSchedulers(); | 72 | InitializeSchedulers(); |
| @@ -131,19 +131,19 @@ struct KernelCore::Impl { | |||
| 131 | } | 131 | } |
| 132 | 132 | ||
| 133 | // Creates the default system resource limit | 133 | // Creates the default system resource limit |
| 134 | void InitializeSystemResourceLimit(KernelCore& kernel) { | 134 | void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { |
| 135 | system_resource_limit = ResourceLimit::Create(kernel); | 135 | system_resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 136 | 136 | ||
| 137 | // If setting the default system values fails, then something seriously wrong has occurred. | 137 | // If setting the default system values fails, then something seriously wrong has occurred. |
| 138 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000) | 138 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemory, 0x100000000) |
| 139 | .IsSuccess()); | 139 | .IsSuccess()); |
| 140 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess()); | 140 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Threads, 800).IsSuccess()); |
| 141 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess()); | 141 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Events, 700).IsSuccess()); |
| 142 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess()); | 142 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemory, 200) |
| 143 | ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); | 143 | .IsSuccess()); |
| 144 | ASSERT(system_resource_limit->SetLimitValue(LimitableResource::Sessions, 900).IsSuccess()); | ||
| 144 | 145 | ||
| 145 | if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) || | 146 | if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemory, 0x60000)) { |
| 146 | !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) { | ||
| 147 | UNREACHABLE(); | 147 | UNREACHABLE(); |
| 148 | } | 148 | } |
| 149 | } | 149 | } |
| @@ -320,7 +320,7 @@ struct KernelCore::Impl { | |||
| 320 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; | 320 | std::unique_ptr<Kernel::GlobalSchedulerContext> global_scheduler_context; |
| 321 | Kernel::TimeManager time_manager; | 321 | Kernel::TimeManager time_manager; |
| 322 | 322 | ||
| 323 | std::shared_ptr<ResourceLimit> system_resource_limit; | 323 | std::shared_ptr<KResourceLimit> system_resource_limit; |
| 324 | 324 | ||
| 325 | std::shared_ptr<Core::Timing::EventType> preemption_event; | 325 | std::shared_ptr<Core::Timing::EventType> preemption_event; |
| 326 | 326 | ||
| @@ -390,7 +390,7 @@ void KernelCore::Shutdown() { | |||
| 390 | impl->Shutdown(); | 390 | impl->Shutdown(); |
| 391 | } | 391 | } |
| 392 | 392 | ||
| 393 | std::shared_ptr<ResourceLimit> KernelCore::GetSystemResourceLimit() const { | 393 | std::shared_ptr<KResourceLimit> KernelCore::GetSystemResourceLimit() const { |
| 394 | return impl->system_resource_limit; | 394 | return impl->system_resource_limit; |
| 395 | } | 395 | } |
| 396 | 396 | ||
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e7c77727b..806a0d986 100644 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h | |||
| @@ -38,7 +38,7 @@ class GlobalSchedulerContext; | |||
| 38 | class HandleTable; | 38 | class HandleTable; |
| 39 | class PhysicalCore; | 39 | class PhysicalCore; |
| 40 | class Process; | 40 | class Process; |
| 41 | class ResourceLimit; | 41 | class KResourceLimit; |
| 42 | class KScheduler; | 42 | class KScheduler; |
| 43 | class SharedMemory; | 43 | class SharedMemory; |
| 44 | class ServiceThread; | 44 | class ServiceThread; |
| @@ -85,7 +85,7 @@ public: | |||
| 85 | void Shutdown(); | 85 | void Shutdown(); |
| 86 | 86 | ||
| 87 | /// Retrieves a shared pointer to the system resource limit instance. | 87 | /// Retrieves a shared pointer to the system resource limit instance. |
| 88 | std::shared_ptr<ResourceLimit> GetSystemResourceLimit() const; | 88 | std::shared_ptr<KResourceLimit> GetSystemResourceLimit() const; |
| 89 | 89 | ||
| 90 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. | 90 | /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. |
| 91 | std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; | 91 | std::shared_ptr<KThread> RetrieveThreadFromGlobalHandleTable(Handle handle) const; |
diff --git a/src/core/hle/kernel/memory/page_table.cpp b/src/core/hle/kernel/memory/page_table.cpp index 080886554..7de91c768 100644 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp | |||
| @@ -7,6 +7,7 @@ | |||
| 7 | #include "common/scope_exit.h" | 7 | #include "common/scope_exit.h" |
| 8 | #include "core/core.h" | 8 | #include "core/core.h" |
| 9 | #include "core/hle/kernel/errors.h" | 9 | #include "core/hle/kernel/errors.h" |
| 10 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 10 | #include "core/hle/kernel/kernel.h" | 11 | #include "core/hle/kernel/kernel.h" |
| 11 | #include "core/hle/kernel/memory/address_space_info.h" | 12 | #include "core/hle/kernel/memory/address_space_info.h" |
| 12 | #include "core/hle/kernel/memory/memory_block.h" | 13 | #include "core/hle/kernel/memory/memory_block.h" |
| @@ -15,7 +16,6 @@ | |||
| 15 | #include "core/hle/kernel/memory/page_table.h" | 16 | #include "core/hle/kernel/memory/page_table.h" |
| 16 | #include "core/hle/kernel/memory/system_control.h" | 17 | #include "core/hle/kernel/memory/system_control.h" |
| 17 | #include "core/hle/kernel/process.h" | 18 | #include "core/hle/kernel/process.h" |
| 18 | #include "core/hle/kernel/resource_limit.h" | ||
| 19 | #include "core/memory.h" | 19 | #include "core/memory.h" |
| 20 | 20 | ||
| 21 | namespace Kernel::Memory { | 21 | namespace Kernel::Memory { |
| @@ -414,7 +414,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 414 | const std::size_t remaining_pages{remaining_size / PageSize}; | 414 | const std::size_t remaining_pages{remaining_size / PageSize}; |
| 415 | 415 | ||
| 416 | if (process->GetResourceLimit() && | 416 | if (process->GetResourceLimit() && |
| 417 | !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) { | 417 | !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, remaining_size)) { |
| 418 | return ERR_RESOURCE_LIMIT_EXCEEDED; | 418 | return ERR_RESOURCE_LIMIT_EXCEEDED; |
| 419 | } | 419 | } |
| 420 | 420 | ||
| @@ -422,7 +422,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 422 | { | 422 | { |
| 423 | auto block_guard = detail::ScopeExit([&] { | 423 | auto block_guard = detail::ScopeExit([&] { |
| 424 | system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); | 424 | system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); |
| 425 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); | 425 | process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, remaining_size); |
| 426 | }); | 426 | }); |
| 427 | 427 | ||
| 428 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, | 428 | CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, |
| @@ -474,7 +474,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { | |||
| 474 | CASCADE_CODE(UnmapMemory(addr, size)); | 474 | CASCADE_CODE(UnmapMemory(addr, size)); |
| 475 | 475 | ||
| 476 | auto process{system.Kernel().CurrentProcess()}; | 476 | auto process{system.Kernel().CurrentProcess()}; |
| 477 | process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); | 477 | process->GetResourceLimit()->Release(LimitableResource::PhysicalMemory, mapped_size); |
| 478 | physical_memory_usage -= mapped_size; | 478 | physical_memory_usage -= mapped_size; |
| 479 | 479 | ||
| 480 | return RESULT_SUCCESS; | 480 | return RESULT_SUCCESS; |
| @@ -783,7 +783,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) { | |||
| 783 | 783 | ||
| 784 | auto process{system.Kernel().CurrentProcess()}; | 784 | auto process{system.Kernel().CurrentProcess()}; |
| 785 | if (process->GetResourceLimit() && delta != 0 && | 785 | if (process->GetResourceLimit() && delta != 0 && |
| 786 | !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) { | 786 | !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemory, delta)) { |
| 787 | return ERR_RESOURCE_LIMIT_EXCEEDED; | 787 | return ERR_RESOURCE_LIMIT_EXCEEDED; |
| 788 | } | 788 | } |
| 789 | 789 | ||
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0edbfc4cc..afdb27c54 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -15,6 +15,7 @@ | |||
| 15 | #include "core/file_sys/program_metadata.h" | 15 | #include "core/file_sys/program_metadata.h" |
| 16 | #include "core/hle/kernel/code_set.h" | 16 | #include "core/hle/kernel/code_set.h" |
| 17 | #include "core/hle/kernel/errors.h" | 17 | #include "core/hle/kernel/errors.h" |
| 18 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 18 | #include "core/hle/kernel/k_scheduler.h" | 19 | #include "core/hle/kernel/k_scheduler.h" |
| 19 | #include "core/hle/kernel/k_thread.h" | 20 | #include "core/hle/kernel/k_thread.h" |
| 20 | #include "core/hle/kernel/kernel.h" | 21 | #include "core/hle/kernel/kernel.h" |
| @@ -22,7 +23,6 @@ | |||
| 22 | #include "core/hle/kernel/memory/page_table.h" | 23 | #include "core/hle/kernel/memory/page_table.h" |
| 23 | #include "core/hle/kernel/memory/slab_heap.h" | 24 | #include "core/hle/kernel/memory/slab_heap.h" |
| 24 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 25 | #include "core/hle/kernel/resource_limit.h" | ||
| 26 | #include "core/hle/lock.h" | 26 | #include "core/hle/lock.h" |
| 27 | #include "core/memory.h" | 27 | #include "core/memory.h" |
| 28 | #include "core/settings.h" | 28 | #include "core/settings.h" |
| @@ -116,7 +116,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 116 | 116 | ||
| 117 | std::shared_ptr<Process> process = std::make_shared<Process>(system); | 117 | std::shared_ptr<Process> process = std::make_shared<Process>(system); |
| 118 | process->name = std::move(name); | 118 | process->name = std::move(name); |
| 119 | process->resource_limit = ResourceLimit::Create(kernel); | 119 | process->resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 120 | process->status = ProcessStatus::Created; | 120 | process->status = ProcessStatus::Created; |
| 121 | process->program_id = 0; | 121 | process->program_id = 0; |
| 122 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() | 122 | process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() |
| @@ -132,7 +132,7 @@ std::shared_ptr<Process> Process::Create(Core::System& system, std::string name, | |||
| 132 | return process; | 132 | return process; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | std::shared_ptr<ResourceLimit> Process::GetResourceLimit() const { | 135 | std::shared_ptr<KResourceLimit> Process::GetResourceLimit() const { |
| 136 | return resource_limit; | 136 | return resource_limit; |
| 137 | } | 137 | } |
| 138 | 138 | ||
| @@ -154,7 +154,7 @@ void Process::DecrementThreadCount() { | |||
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | u64 Process::GetTotalPhysicalMemoryAvailable() const { | 156 | u64 Process::GetTotalPhysicalMemoryAvailable() const { |
| 157 | const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + | 157 | const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemory) + |
| 158 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + | 158 | page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + |
| 159 | main_thread_stack_size}; | 159 | main_thread_stack_size}; |
| 160 | 160 | ||
| @@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, | |||
| 308 | 308 | ||
| 309 | // Set initial resource limits | 309 | // Set initial resource limits |
| 310 | resource_limit->SetLimitValue( | 310 | resource_limit->SetLimitValue( |
| 311 | ResourceType::PhysicalMemory, | 311 | LimitableResource::PhysicalMemory, |
| 312 | kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); | 312 | kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); |
| 313 | resource_limit->SetLimitValue(ResourceType::Threads, 608); | 313 | resource_limit->SetLimitValue(LimitableResource::Threads, 608); |
| 314 | resource_limit->SetLimitValue(ResourceType::Events, 700); | 314 | resource_limit->SetLimitValue(LimitableResource::Events, 700); |
| 315 | resource_limit->SetLimitValue(ResourceType::TransferMemory, 128); | 315 | resource_limit->SetLimitValue(LimitableResource::TransferMemory, 128); |
| 316 | resource_limit->SetLimitValue(ResourceType::Sessions, 894); | 316 | resource_limit->SetLimitValue(LimitableResource::Sessions, 894); |
| 317 | ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size)); | 317 | ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemory, code_size)); |
| 318 | 318 | ||
| 319 | // Create TLS region | 319 | // Create TLS region |
| 320 | tls_region_address = CreateTLSRegion(); | 320 | tls_region_address = CreateTLSRegion(); |
| @@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { | |||
| 331 | ChangeStatus(ProcessStatus::Running); | 331 | ChangeStatus(ProcessStatus::Running); |
| 332 | 332 | ||
| 333 | SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); | 333 | SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); |
| 334 | resource_limit->Reserve(ResourceType::Threads, 1); | 334 | resource_limit->Reserve(LimitableResource::Threads, 1); |
| 335 | resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); | 335 | resource_limit->Reserve(LimitableResource::PhysicalMemory, main_thread_stack_size); |
| 336 | } | 336 | } |
| 337 | 337 | ||
| 338 | void Process::PrepareForTermination() { | 338 | void Process::PrepareForTermination() { |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 26e647743..c8af76ce8 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -29,7 +29,7 @@ class ProgramMetadata; | |||
| 29 | namespace Kernel { | 29 | namespace Kernel { |
| 30 | 30 | ||
| 31 | class KernelCore; | 31 | class KernelCore; |
| 32 | class ResourceLimit; | 32 | class KResourceLimit; |
| 33 | class KThread; | 33 | class KThread; |
| 34 | class TLSPage; | 34 | class TLSPage; |
| 35 | 35 | ||
| @@ -170,7 +170,7 @@ public: | |||
| 170 | } | 170 | } |
| 171 | 171 | ||
| 172 | /// Gets the resource limit descriptor for this process | 172 | /// Gets the resource limit descriptor for this process |
| 173 | std::shared_ptr<ResourceLimit> GetResourceLimit() const; | 173 | std::shared_ptr<KResourceLimit> GetResourceLimit() const; |
| 174 | 174 | ||
| 175 | /// Gets the ideal CPU core ID for this process | 175 | /// Gets the ideal CPU core ID for this process |
| 176 | u8 GetIdealCoreId() const { | 176 | u8 GetIdealCoreId() const { |
| @@ -402,7 +402,7 @@ private: | |||
| 402 | u32 system_resource_size = 0; | 402 | u32 system_resource_size = 0; |
| 403 | 403 | ||
| 404 | /// Resource limit descriptor for this process | 404 | /// Resource limit descriptor for this process |
| 405 | std::shared_ptr<ResourceLimit> resource_limit; | 405 | std::shared_ptr<KResourceLimit> resource_limit; |
| 406 | 406 | ||
| 407 | /// The ideal CPU core for this process, threads are scheduled on this core by default. | 407 | /// The ideal CPU core for this process, threads are scheduled on this core by default. |
| 408 | u8 ideal_core = 0; | 408 | u8 ideal_core = 0; |
diff --git a/src/core/hle/kernel/resource_limit.cpp b/src/core/hle/kernel/resource_limit.cpp deleted file mode 100644 index 7bf50339d..000000000 --- a/src/core/hle/kernel/resource_limit.cpp +++ /dev/null | |||
| @@ -1,73 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #include "core/hle/kernel/errors.h" | ||
| 6 | #include "core/hle/kernel/resource_limit.h" | ||
| 7 | #include "core/hle/result.h" | ||
| 8 | |||
| 9 | namespace Kernel { | ||
| 10 | namespace { | ||
| 11 | constexpr std::size_t ResourceTypeToIndex(ResourceType type) { | ||
| 12 | return static_cast<std::size_t>(type); | ||
| 13 | } | ||
| 14 | } // Anonymous namespace | ||
| 15 | |||
| 16 | ResourceLimit::ResourceLimit(KernelCore& kernel) : Object{kernel} {} | ||
| 17 | ResourceLimit::~ResourceLimit() = default; | ||
| 18 | |||
| 19 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount) { | ||
| 20 | return Reserve(resource, amount, 10000000000); | ||
| 21 | } | ||
| 22 | |||
| 23 | bool ResourceLimit::Reserve(ResourceType resource, s64 amount, u64 timeout) { | ||
| 24 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 25 | |||
| 26 | s64 new_value = current[index] + amount; | ||
| 27 | if (new_value > limit[index] && available[index] + amount <= limit[index]) { | ||
| 28 | // TODO(bunnei): This is wrong for multicore, we should wait the calling thread for timeout | ||
| 29 | new_value = current[index] + amount; | ||
| 30 | } | ||
| 31 | |||
| 32 | if (new_value <= limit[index]) { | ||
| 33 | current[index] = new_value; | ||
| 34 | return true; | ||
| 35 | } | ||
| 36 | return false; | ||
| 37 | } | ||
| 38 | |||
| 39 | void ResourceLimit::Release(ResourceType resource, u64 amount) { | ||
| 40 | Release(resource, amount, amount); | ||
| 41 | } | ||
| 42 | |||
| 43 | void ResourceLimit::Release(ResourceType resource, u64 used_amount, u64 available_amount) { | ||
| 44 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 45 | |||
| 46 | current[index] -= used_amount; | ||
| 47 | available[index] -= available_amount; | ||
| 48 | } | ||
| 49 | |||
| 50 | std::shared_ptr<ResourceLimit> ResourceLimit::Create(KernelCore& kernel) { | ||
| 51 | return std::make_shared<ResourceLimit>(kernel); | ||
| 52 | } | ||
| 53 | |||
| 54 | s64 ResourceLimit::GetCurrentResourceValue(ResourceType resource) const { | ||
| 55 | return limit.at(ResourceTypeToIndex(resource)) - current.at(ResourceTypeToIndex(resource)); | ||
| 56 | } | ||
| 57 | |||
| 58 | s64 ResourceLimit::GetMaxResourceValue(ResourceType resource) const { | ||
| 59 | return limit.at(ResourceTypeToIndex(resource)); | ||
| 60 | } | ||
| 61 | |||
| 62 | ResultCode ResourceLimit::SetLimitValue(ResourceType resource, s64 value) { | ||
| 63 | const std::size_t index{ResourceTypeToIndex(resource)}; | ||
| 64 | if (current[index] <= value) { | ||
| 65 | limit[index] = value; | ||
| 66 | return RESULT_SUCCESS; | ||
| 67 | } else { | ||
| 68 | LOG_ERROR(Kernel, "Limit value is too large! resource={}, value={}, index={}", resource, | ||
| 69 | value, index); | ||
| 70 | return ERR_INVALID_STATE; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/resource_limit.h b/src/core/hle/kernel/resource_limit.h deleted file mode 100644 index 464d4f2a6..000000000 --- a/src/core/hle/kernel/resource_limit.h +++ /dev/null | |||
| @@ -1,106 +0,0 @@ | |||
| 1 | // Copyright 2015 Citra Emulator Project | ||
| 2 | // Licensed under GPLv2 or any later version | ||
| 3 | // Refer to the license.txt file included. | ||
| 4 | |||
| 5 | #pragma once | ||
| 6 | |||
| 7 | #include <array> | ||
| 8 | #include <memory> | ||
| 9 | |||
| 10 | #include "common/common_types.h" | ||
| 11 | #include "core/hle/kernel/object.h" | ||
| 12 | |||
| 13 | union ResultCode; | ||
| 14 | |||
| 15 | namespace Kernel { | ||
| 16 | |||
| 17 | class KernelCore; | ||
| 18 | |||
| 19 | enum class ResourceType : u32 { | ||
| 20 | PhysicalMemory, | ||
| 21 | Threads, | ||
| 22 | Events, | ||
| 23 | TransferMemory, | ||
| 24 | Sessions, | ||
| 25 | |||
| 26 | // Used as a count, not an actual type. | ||
| 27 | ResourceTypeCount | ||
| 28 | }; | ||
| 29 | |||
| 30 | constexpr bool IsValidResourceType(ResourceType type) { | ||
| 31 | return type < ResourceType::ResourceTypeCount; | ||
| 32 | } | ||
| 33 | |||
| 34 | class ResourceLimit final : public Object { | ||
| 35 | public: | ||
| 36 | explicit ResourceLimit(KernelCore& kernel); | ||
| 37 | ~ResourceLimit() override; | ||
| 38 | |||
| 39 | /// Creates a resource limit object. | ||
| 40 | static std::shared_ptr<ResourceLimit> Create(KernelCore& kernel); | ||
| 41 | |||
| 42 | std::string GetTypeName() const override { | ||
| 43 | return "ResourceLimit"; | ||
| 44 | } | ||
| 45 | std::string GetName() const override { | ||
| 46 | return GetTypeName(); | ||
| 47 | } | ||
| 48 | |||
| 49 | static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; | ||
| 50 | HandleType GetHandleType() const override { | ||
| 51 | return HANDLE_TYPE; | ||
| 52 | } | ||
| 53 | |||
| 54 | bool Reserve(ResourceType resource, s64 amount); | ||
| 55 | bool Reserve(ResourceType resource, s64 amount, u64 timeout); | ||
| 56 | void Release(ResourceType resource, u64 amount); | ||
| 57 | void Release(ResourceType resource, u64 used_amount, u64 available_amount); | ||
| 58 | |||
| 59 | /** | ||
| 60 | * Gets the current value for the specified resource. | ||
| 61 | * @param resource Requested resource type | ||
| 62 | * @returns The current value of the resource type | ||
| 63 | */ | ||
| 64 | s64 GetCurrentResourceValue(ResourceType resource) const; | ||
| 65 | |||
| 66 | /** | ||
| 67 | * Gets the max value for the specified resource. | ||
| 68 | * @param resource Requested resource type | ||
| 69 | * @returns The max value of the resource type | ||
| 70 | */ | ||
| 71 | s64 GetMaxResourceValue(ResourceType resource) const; | ||
| 72 | |||
| 73 | /** | ||
| 74 | * Sets the limit value for a given resource type. | ||
| 75 | * | ||
| 76 | * @param resource The resource type to apply the limit to. | ||
| 77 | * @param value The limit to apply to the given resource type. | ||
| 78 | * | ||
| 79 | * @return A result code indicating if setting the limit value | ||
| 80 | * was successful or not. | ||
| 81 | * | ||
| 82 | * @note The supplied limit value *must* be greater than or equal to | ||
| 83 | * the current resource value for the given resource type, | ||
| 84 | * otherwise ERR_INVALID_STATE will be returned. | ||
| 85 | */ | ||
| 86 | ResultCode SetLimitValue(ResourceType resource, s64 value); | ||
| 87 | |||
| 88 | void Finalize() override {} | ||
| 89 | |||
| 90 | private: | ||
| 91 | // TODO(Subv): Increment resource limit current values in their respective Kernel::T::Create | ||
| 92 | // functions | ||
| 93 | // | ||
| 94 | // Currently we have no way of distinguishing if a Create was called by the running application, | ||
| 95 | // or by a service module. Approach this once we have separated the service modules into their | ||
| 96 | // own processes | ||
| 97 | |||
| 98 | using ResourceArray = | ||
| 99 | std::array<s64, static_cast<std::size_t>(ResourceType::ResourceTypeCount)>; | ||
| 100 | |||
| 101 | ResourceArray limit{}; | ||
| 102 | ResourceArray current{}; | ||
| 103 | ResourceArray available{}; | ||
| 104 | }; | ||
| 105 | |||
| 106 | } // namespace Kernel | ||
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7fd514e9d..74eb90100 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -26,6 +26,7 @@ | |||
| 26 | #include "core/hle/kernel/handle_table.h" | 26 | #include "core/hle/kernel/handle_table.h" |
| 27 | #include "core/hle/kernel/k_address_arbiter.h" | 27 | #include "core/hle/kernel/k_address_arbiter.h" |
| 28 | #include "core/hle/kernel/k_condition_variable.h" | 28 | #include "core/hle/kernel/k_condition_variable.h" |
| 29 | #include "core/hle/kernel/k_resource_limit.h" | ||
| 29 | #include "core/hle/kernel/k_scheduler.h" | 30 | #include "core/hle/kernel/k_scheduler.h" |
| 30 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" | 31 | #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" |
| 31 | #include "core/hle/kernel/k_synchronization_object.h" | 32 | #include "core/hle/kernel/k_synchronization_object.h" |
| @@ -37,7 +38,6 @@ | |||
| 37 | #include "core/hle/kernel/physical_core.h" | 38 | #include "core/hle/kernel/physical_core.h" |
| 38 | #include "core/hle/kernel/process.h" | 39 | #include "core/hle/kernel/process.h" |
| 39 | #include "core/hle/kernel/readable_event.h" | 40 | #include "core/hle/kernel/readable_event.h" |
| 40 | #include "core/hle/kernel/resource_limit.h" | ||
| 41 | #include "core/hle/kernel/shared_memory.h" | 41 | #include "core/hle/kernel/shared_memory.h" |
| 42 | #include "core/hle/kernel/svc.h" | 42 | #include "core/hle/kernel/svc.h" |
| 43 | #include "core/hle/kernel/svc_results.h" | 43 | #include "core/hle/kernel/svc_results.h" |
| @@ -141,7 +141,7 @@ enum class ResourceLimitValueType { | |||
| 141 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, | 141 | ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, |
| 142 | u32 resource_type, ResourceLimitValueType value_type) { | 142 | u32 resource_type, ResourceLimitValueType value_type) { |
| 143 | std::lock_guard lock{HLE::g_hle_lock}; | 143 | std::lock_guard lock{HLE::g_hle_lock}; |
| 144 | const auto type = static_cast<ResourceType>(resource_type); | 144 | const auto type = static_cast<LimitableResource>(resource_type); |
| 145 | if (!IsValidResourceType(type)) { | 145 | if (!IsValidResourceType(type)) { |
| 146 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | 146 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); |
| 147 | return ERR_INVALID_ENUM_VALUE; | 147 | return ERR_INVALID_ENUM_VALUE; |
| @@ -151,7 +151,7 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 151 | ASSERT(current_process != nullptr); | 151 | ASSERT(current_process != nullptr); |
| 152 | 152 | ||
| 153 | const auto resource_limit_object = | 153 | const auto resource_limit_object = |
| 154 | current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); | 154 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); |
| 155 | if (!resource_limit_object) { | 155 | if (!resource_limit_object) { |
| 156 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 156 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", |
| 157 | resource_limit); | 157 | resource_limit); |
| @@ -159,10 +159,10 @@ ResultVal<s64> RetrieveResourceLimitValue(Core::System& system, Handle resource_ | |||
| 159 | } | 159 | } |
| 160 | 160 | ||
| 161 | if (value_type == ResourceLimitValueType::CurrentValue) { | 161 | if (value_type == ResourceLimitValueType::CurrentValue) { |
| 162 | return MakeResult(resource_limit_object->GetCurrentResourceValue(type)); | 162 | return MakeResult(resource_limit_object->GetCurrentValue(type)); |
| 163 | } | 163 | } |
| 164 | 164 | ||
| 165 | return MakeResult(resource_limit_object->GetMaxResourceValue(type)); | 165 | return MakeResult(resource_limit_object->GetLimitValue(type)); |
| 166 | } | 166 | } |
| 167 | } // Anonymous namespace | 167 | } // Anonymous namespace |
| 168 | 168 | ||
| @@ -312,7 +312,7 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, | |||
| 312 | return ERR_NOT_FOUND; | 312 | return ERR_NOT_FOUND; |
| 313 | } | 313 | } |
| 314 | 314 | ||
| 315 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1)); | 315 | ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::Sessions, 1)); |
| 316 | 316 | ||
| 317 | auto client_port = it->second; | 317 | auto client_port = it->second; |
| 318 | 318 | ||
| @@ -1450,7 +1450,8 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e | |||
| 1450 | Svc::ResultInvalidPriority); | 1450 | Svc::ResultInvalidPriority); |
| 1451 | R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); | 1451 | R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); |
| 1452 | 1452 | ||
| 1453 | ASSERT(process.GetResourceLimit()->Reserve(ResourceType::Threads, 1)); | 1453 | ASSERT(process.GetResourceLimit()->Reserve( |
| 1454 | LimitableResource::Threads, 1, system.CoreTiming().GetGlobalTimeNs().count() + 100000000)); | ||
| 1454 | 1455 | ||
| 1455 | std::shared_ptr<KThread> thread; | 1456 | std::shared_ptr<KThread> thread; |
| 1456 | { | 1457 | { |
| @@ -1972,7 +1973,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) | |||
| 1972 | LOG_DEBUG(Kernel_SVC, "called"); | 1973 | LOG_DEBUG(Kernel_SVC, "called"); |
| 1973 | 1974 | ||
| 1974 | auto& kernel = system.Kernel(); | 1975 | auto& kernel = system.Kernel(); |
| 1975 | auto resource_limit = ResourceLimit::Create(kernel); | 1976 | auto resource_limit = std::make_shared<KResourceLimit>(kernel, system); |
| 1976 | 1977 | ||
| 1977 | auto* const current_process = kernel.CurrentProcess(); | 1978 | auto* const current_process = kernel.CurrentProcess(); |
| 1978 | ASSERT(current_process != nullptr); | 1979 | ASSERT(current_process != nullptr); |
| @@ -2019,7 +2020,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2019 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, | 2020 | LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, |
| 2020 | resource_type, value); | 2021 | resource_type, value); |
| 2021 | 2022 | ||
| 2022 | const auto type = static_cast<ResourceType>(resource_type); | 2023 | const auto type = static_cast<LimitableResource>(resource_type); |
| 2023 | if (!IsValidResourceType(type)) { | 2024 | if (!IsValidResourceType(type)) { |
| 2024 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); | 2025 | LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); |
| 2025 | return ERR_INVALID_ENUM_VALUE; | 2026 | return ERR_INVALID_ENUM_VALUE; |
| @@ -2029,7 +2030,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2029 | ASSERT(current_process != nullptr); | 2030 | ASSERT(current_process != nullptr); |
| 2030 | 2031 | ||
| 2031 | auto resource_limit_object = | 2032 | auto resource_limit_object = |
| 2032 | current_process->GetHandleTable().Get<ResourceLimit>(resource_limit); | 2033 | current_process->GetHandleTable().Get<KResourceLimit>(resource_limit); |
| 2033 | if (!resource_limit_object) { | 2034 | if (!resource_limit_object) { |
| 2034 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", | 2035 | LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", |
| 2035 | resource_limit); | 2036 | resource_limit); |
| @@ -2041,8 +2042,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour | |||
| 2041 | LOG_ERROR( | 2042 | LOG_ERROR( |
| 2042 | Kernel_SVC, | 2043 | Kernel_SVC, |
| 2043 | "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", | 2044 | "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", |
| 2044 | resource_limit_object->GetMaxResourceValue(type), resource_type, | 2045 | resource_limit_object->GetLimitValue(type), resource_type, |
| 2045 | resource_limit_object->GetCurrentResourceValue(type)); | 2046 | resource_limit_object->GetCurrentValue(type)); |
| 2046 | return set_result; | 2047 | return set_result; |
| 2047 | } | 2048 | } |
| 2048 | 2049 | ||
diff --git a/src/core/hle/service/acc/profile_manager.cpp b/src/core/hle/service/acc/profile_manager.cpp index d9865d56f..50b2c58e2 100644 --- a/src/core/hle/service/acc/profile_manager.cpp +++ b/src/core/hle/service/acc/profile_manager.cpp | |||
| @@ -41,12 +41,18 @@ constexpr char ACC_SAVE_AVATORS_BASE_PATH[] = "/system/save/8000000000000010/su/ | |||
| 41 | ProfileManager::ProfileManager() { | 41 | ProfileManager::ProfileManager() { |
| 42 | ParseUserSaveFile(); | 42 | ParseUserSaveFile(); |
| 43 | 43 | ||
| 44 | if (user_count == 0) | 44 | // Create an user if none are present |
| 45 | if (user_count == 0) { | ||
| 45 | CreateNewUser(UUID::Generate(), "yuzu"); | 46 | CreateNewUser(UUID::Generate(), "yuzu"); |
| 47 | } | ||
| 46 | 48 | ||
| 47 | auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); | 49 | auto current = std::clamp<int>(Settings::values.current_user, 0, MAX_USERS - 1); |
| 48 | if (UserExistsIndex(current)) | 50 | |
| 51 | // If user index don't exist. Load the first user and change the active user | ||
| 52 | if (!UserExistsIndex(current)) { | ||
| 49 | current = 0; | 53 | current = 0; |
| 54 | Settings::values.current_user = 0; | ||
| 55 | } | ||
| 50 | 56 | ||
| 51 | OpenUser(*GetUser(current)); | 57 | OpenUser(*GetUser(current)); |
| 52 | } | 58 | } |
diff --git a/src/core/settings.cpp b/src/core/settings.cpp index 39306509a..2ae5196e0 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp | |||
| @@ -70,6 +70,9 @@ void LogSettings() { | |||
| 70 | log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); | 70 | log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); |
| 71 | log_setting("Audio_OutputDevice", values.audio_device_id); | 71 | log_setting("Audio_OutputDevice", values.audio_device_id); |
| 72 | log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); | 72 | log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd); |
| 73 | log_setting("DataStorage_CacheDir", Common::FS::GetUserPath(Common::FS::UserPath::CacheDir)); | ||
| 74 | log_setting("DataStorage_ConfigDir", Common::FS::GetUserPath(Common::FS::UserPath::ConfigDir)); | ||
| 75 | log_setting("DataStorage_LoadDir", Common::FS::GetUserPath(Common::FS::UserPath::LoadDir)); | ||
| 73 | log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)); | 76 | log_setting("DataStorage_NandDir", Common::FS::GetUserPath(Common::FS::UserPath::NANDDir)); |
| 74 | log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)); | 77 | log_setting("DataStorage_SdmcDir", Common::FS::GetUserPath(Common::FS::UserPath::SDMCDir)); |
| 75 | log_setting("Debugging_ProgramArgs", values.program_args); | 78 | log_setting("Debugging_ProgramArgs", values.program_args); |
diff --git a/src/video_core/host_shaders/CMakeLists.txt b/src/video_core/host_shaders/CMakeLists.txt index 73f331d4c..28f2b8614 100644 --- a/src/video_core/host_shaders/CMakeLists.txt +++ b/src/video_core/host_shaders/CMakeLists.txt | |||
| @@ -20,6 +20,7 @@ set(SHADER_FILES | |||
| 20 | find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED) | 20 | find_program(GLSLANGVALIDATOR "glslangValidator" REQUIRED) |
| 21 | 21 | ||
| 22 | set(GLSL_FLAGS "") | 22 | set(GLSL_FLAGS "") |
| 23 | set(QUIET_FLAG "--quiet") | ||
| 23 | 24 | ||
| 24 | set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) | 25 | set(SHADER_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/include) |
| 25 | set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) | 26 | set(SHADER_DIR ${SHADER_INCLUDE}/video_core/host_shaders) |
| @@ -28,6 +29,23 @@ set(HOST_SHADERS_INCLUDE ${SHADER_INCLUDE} PARENT_SCOPE) | |||
| 28 | set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) | 29 | set(INPUT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/source_shader.h.in) |
| 29 | set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) | 30 | set(HEADER_GENERATOR ${CMAKE_CURRENT_SOURCE_DIR}/StringShaderHeader.cmake) |
| 30 | 31 | ||
| 32 | # Check if `--quiet` is available on host's glslangValidator version | ||
| 33 | # glslangValidator prints to STDERR iff an unrecognized flag is passed to it | ||
| 34 | execute_process( | ||
| 35 | COMMAND | ||
| 36 | ${GLSLANGVALIDATOR} ${QUIET_FLAG} | ||
| 37 | ERROR_VARIABLE | ||
| 38 | GLSLANG_ERROR | ||
| 39 | # STDOUT variable defined to silence unnecessary output during CMake configuration | ||
| 40 | OUTPUT_VARIABLE | ||
| 41 | GLSLANG_OUTPUT | ||
| 42 | ) | ||
| 43 | |||
| 44 | if (NOT GLSLANG_ERROR STREQUAL "") | ||
| 45 | message(WARNING "Refusing to use unavailable flag `${QUIET_FLAG}` on `${GLSLANGVALIDATOR}`") | ||
| 46 | set(QUIET_FLAG "") | ||
| 47 | endif() | ||
| 48 | |||
| 31 | foreach(FILENAME IN ITEMS ${SHADER_FILES}) | 49 | foreach(FILENAME IN ITEMS ${SHADER_FILES}) |
| 32 | string(REPLACE "." "_" SHADER_NAME ${FILENAME}) | 50 | string(REPLACE "." "_" SHADER_NAME ${FILENAME}) |
| 33 | set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) | 51 | set(SOURCE_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${FILENAME}) |
| @@ -55,7 +73,7 @@ foreach(FILENAME IN ITEMS ${SHADER_FILES}) | |||
| 55 | OUTPUT | 73 | OUTPUT |
| 56 | ${SPIRV_HEADER_FILE} | 74 | ${SPIRV_HEADER_FILE} |
| 57 | COMMAND | 75 | COMMAND |
| 58 | ${GLSLANGVALIDATOR} -V --quiet ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} | 76 | ${GLSLANGVALIDATOR} -V ${QUIET_FLAG} ${GLSL_FLAGS} --variable-name ${SPIRV_VARIABLE_NAME} -o ${SPIRV_HEADER_FILE} ${SOURCE_FILE} |
| 59 | MAIN_DEPENDENCY | 77 | MAIN_DEPENDENCY |
| 60 | ${SOURCE_FILE} | 78 | ${SOURCE_FILE} |
| 61 | ) | 79 | ) |
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index fbe36046b..1ab5bcbb9 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp | |||
| @@ -580,9 +580,7 @@ void ConfigureInputPlayer::ApplyConfiguration() { | |||
| 580 | if (player_index == 0) { | 580 | if (player_index == 0) { |
| 581 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; | 581 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; |
| 582 | const auto handheld_connected = handheld.connected; | 582 | const auto handheld_connected = handheld.connected; |
| 583 | if (player.controller_type == Settings::ControllerType::Handheld) { | 583 | handheld = player; |
| 584 | handheld = player; | ||
| 585 | } | ||
| 586 | handheld.connected = handheld_connected; | 584 | handheld.connected = handheld_connected; |
| 587 | } | 585 | } |
| 588 | } | 586 | } |
| @@ -596,7 +594,7 @@ void ConfigureInputPlayer::TryConnectSelectedController() { | |||
| 596 | controller_type != Settings::ControllerType::Handheld; | 594 | controller_type != Settings::ControllerType::Handheld; |
| 597 | 595 | ||
| 598 | // Connect Handheld depending on Player 1's controller configuration. | 596 | // Connect Handheld depending on Player 1's controller configuration. |
| 599 | if (player_index == 0 && controller_type == Settings::ControllerType::Handheld) { | 597 | if (player_index == 0) { |
| 600 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; | 598 | auto& handheld = Settings::values.players.GetValue()[HANDHELD_INDEX]; |
| 601 | const auto handheld_connected = ui->groupConnectedController->isChecked() && | 599 | const auto handheld_connected = ui->groupConnectedController->isChecked() && |
| 602 | controller_type == Settings::ControllerType::Handheld; | 600 | controller_type == Settings::ControllerType::Handheld; |
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp index d102a43af..51647a028 100644 --- a/src/yuzu/configuration/configure_profile_manager.cpp +++ b/src/yuzu/configuration/configure_profile_manager.cpp | |||
| @@ -116,8 +116,8 @@ ConfigureProfileManager ::ConfigureProfileManager(QWidget* parent) | |||
| 116 | scene = new QGraphicsScene; | 116 | scene = new QGraphicsScene; |
| 117 | ui->current_user_icon->setScene(scene); | 117 | ui->current_user_icon->setScene(scene); |
| 118 | 118 | ||
| 119 | SetConfiguration(); | ||
| 120 | RetranslateUI(); | 119 | RetranslateUI(); |
| 120 | SetConfiguration(); | ||
| 121 | } | 121 | } |
| 122 | 122 | ||
| 123 | ConfigureProfileManager::~ConfigureProfileManager() = default; | 123 | ConfigureProfileManager::~ConfigureProfileManager() = default; |