From 88a41fdf634192a57a5daed9acf3b9dd93069816 Mon Sep 17 00:00:00 2001 From: pineappleEA Date: Sun, 31 Jan 2021 07:17:28 +0100 Subject: [PATCH] early-access version 1397 --- README.md | 2 +- src/core/CMakeLists.txt | 5 +- .../hle/kernel/k_light_condition_variable.h | 60 +++++++ src/core/hle/kernel/k_resource_limit.cpp | 154 ++++++++++++++++++ src/core/hle/kernel/k_resource_limit.h | 80 +++++++++ src/core/hle/kernel/k_thread.cpp | 4 +- src/core/hle/kernel/kernel.cpp | 30 ++-- src/core/hle/kernel/kernel.h | 4 +- src/core/hle/kernel/memory/page_table.cpp | 13 +- src/core/hle/kernel/process.cpp | 24 +-- src/core/hle/kernel/process.h | 6 +- src/core/hle/kernel/svc.cpp | 27 +-- src/core/hle/service/sockets/bsd.cpp | 12 +- src/core/hle/service/sockets/bsd.h | 1 + 14 files changed, 368 insertions(+), 54 deletions(-) create mode 100755 src/core/hle/kernel/k_light_condition_variable.h create mode 100755 src/core/hle/kernel/k_resource_limit.cpp create mode 100755 src/core/hle/kernel/k_resource_limit.h diff --git a/README.md b/README.md index 69998f6e4..6f4a17980 100755 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ yuzu emulator early access ============= -This is the source code for early-access 1396. +This is the source code for early-access 1397. ## Legal Notice diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 848b7ca7c..f9a7f9679 100755 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -159,9 +159,12 @@ add_library(core STATIC hle/kernel/k_affinity_mask.h hle/kernel/k_condition_variable.cpp hle/kernel/k_condition_variable.h + hle/kernel/k_light_condition_variable.h hle/kernel/k_light_lock.cpp hle/kernel/k_light_lock.h hle/kernel/k_priority_queue.h + hle/kernel/k_resource_limit.cpp + hle/kernel/k_resource_limit.h hle/kernel/k_scheduler.cpp hle/kernel/k_scheduler.h hle/kernel/k_scheduler_lock.h @@ -202,8 +205,6 @@ add_library(core STATIC hle/kernel/process_capability.h hle/kernel/readable_event.cpp hle/kernel/readable_event.h - hle/kernel/resource_limit.cpp - hle/kernel/resource_limit.h hle/kernel/server_port.cpp hle/kernel/server_port.h hle/kernel/server_session.cpp 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 100755 index 000000000..26573a239 --- /dev/null +++ b/src/core/hle/kernel/k_light_condition_variable.h @@ -0,0 +1,60 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include "common/common_types.h" +#include "core/hle/kernel/k_scheduler.h" +#include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" +#include "core/hle/kernel/k_thread_queue.h" +#include "core/hle/kernel/time_manager.h" + +namespace Kernel { +class KernelCore; + +class KLightConditionVariable { +private: + KThreadQueue m_thread_queue; + +public: + KLightConditionVariable(KernelCore& kernel) : m_thread_queue(kernel), kernel(kernel) {} + + void Wait(KLightLock* lock, s64 timeout = -1ll) { + WaitImpl(lock, timeout); + lock->Lock(); + } + + void Broadcast() { + KScopedSchedulerLock lk{kernel}; + while (m_thread_queue.WakeupFrontThread() != nullptr) { + /* We want to signal all threads, and so should continue waking up until there's nothing + * to wake. */ + } + } + +private: + void WaitImpl(KLightLock* lock, s64 timeout) { + KThread* owner = GetCurrentThreadPointer(kernel); + // KHardwareTimer* timer; + + /* Sleep the thread. */ + { + KScopedSchedulerLockAndSleep lk(kernel, owner, timeout); + lock->Unlock(); + + if (!m_thread_queue.SleepThread(owner)) { + lk.CancelSleep(); + return; + } + } + + /* Cancel the task that the sleep setup. */ + kernel.TimeManager().UnscheduleTimeEvent(owner); + } + KernelCore& kernel; +}; +} // 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 100755 index 000000000..3cee8d0f7 --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.cpp @@ -0,0 +1,154 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#include "common/assert.h" +#include "core/core.h" +#include "core/core_timing.h" +#include "core/core_timing_util.h" +#include "core/hle/kernel/k_resource_limit.h" +#include "core/hle/kernel/svc_results.h" + +namespace Kernel { +namespace { +constexpr s64 DefaultTimeout = 10000000000; // 10 seconds +} + +KResourceLimit::KResourceLimit(KernelCore& kernel, Core::System& system) + : Object{kernel}, lock{kernel}, cond_var{kernel}, kernel{kernel}, system(system) {} +KResourceLimit::~KResourceLimit() = default; + +s64 KResourceLimit::GetLimitValue(LimitableResource which) const { + const auto index = static_cast(which); + s64 value{}; + { + KScopedLightLock lk{lock}; + value = limit_values[index]; + ASSERT(value >= 0); + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + } + return value; +} + +s64 KResourceLimit::GetCurrentValue(LimitableResource which) const { + const auto index = static_cast(which); + s64 value{}; + { + KScopedLightLock lk{lock}; + value = current_values[index]; + ASSERT(value >= 0); + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + } + return value; +} + +s64 KResourceLimit::GetPeakValue(LimitableResource which) const { + const auto index = static_cast(which); + s64 value{}; + { + KScopedLightLock lk{lock}; + value = peak_values[index]; + ASSERT(value >= 0); + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + } + return value; +} + +s64 KResourceLimit::GetFreeValue(LimitableResource which) const { + const auto index = static_cast(which); + s64 value{}; + { + KScopedLightLock lk(lock); + ASSERT(current_values[index] >= 0); + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + value = limit_values[index] - current_values[index]; + } + + return value; +} + +ResultCode KResourceLimit::SetLimitValue(LimitableResource which, s64 value) { + const auto index = static_cast(which); + KScopedLightLock lk(lock); + R_UNLESS(current_values[index] <= value, Svc::ResultInvalidState); + + limit_values[index] = value; + + return RESULT_SUCCESS; +} + +bool KResourceLimit::Reserve(LimitableResource which, s64 value) { + return Reserve(which, value, system.CoreTiming().GetGlobalTimeNs().count() + DefaultTimeout); +} + +bool KResourceLimit::Reserve(LimitableResource which, s64 value, s64 timeout) { + ASSERT(value >= 0); + const auto index = static_cast(which); + KScopedLightLock lk(lock); + + ASSERT(current_hints[index] <= current_values[index]); + if (current_hints[index] >= limit_values[index]) { + return false; + } + + // Loop until we reserve or run out of time. + while (true) { + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + + // If we would overflow, don't allow to succeed. + if (current_values[index] + value <= current_values[index]) { + break; + } + + if (current_values[index] + value <= limit_values[index]) { + current_values[index] += value; + current_hints[index] += value; + peak_values[index] = std::max(peak_values[index], current_values[index]); + return true; + } + + if (current_hints[index] + value <= limit_values[index] && + (timeout < 0 || system.CoreTiming().GetGlobalTimeNs().count() < timeout)) { + waiter_count++; + cond_var.Wait(&lock, timeout); + waiter_count--; + } else { + break; + } + } + + return false; +} + +void KResourceLimit::Release(LimitableResource which, s64 value) { + Release(which, value, value); +} + +void KResourceLimit::Release(LimitableResource which, s64 value, s64 hint) { + ASSERT(value >= 0); + ASSERT(hint >= 0); + + const auto index = static_cast(which); + KScopedLightLock lk(lock); + ASSERT(current_values[index] <= limit_values[index]); + ASSERT(current_hints[index] <= current_values[index]); + ASSERT(value <= current_values[index]); + ASSERT(hint <= current_hints[index]); + + current_values[index] -= value; + current_hints[index] -= hint; + + if (waiter_count != 0) { + cond_var.Broadcast(); + } +} + +} // 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 100755 index 000000000..5f916c99c --- /dev/null +++ b/src/core/hle/kernel/k_resource_limit.h @@ -0,0 +1,80 @@ +// Copyright 2020 yuzu Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +// This file references various implementation details from Atmosphere, an open-source firmware for +// the Nintendo Switch. Copyright 2018-2020 Atmosphere-NX. + +#pragma once + +#include +#include "common/common_types.h" +#include "core/hle/kernel/k_light_condition_variable.h" +#include "core/hle/kernel/k_light_lock.h" +#include "core/hle/kernel/object.h" + +union ResultCode; + +namespace Core { +class System; +} + +namespace Kernel { +class KernelCore; +enum class LimitableResource : u32 { + PhysicalMemoryMax = 0, + ThreadCountMax = 1, + EventCountMax = 2, + TransferMemoryCountMax = 3, + SessionCountMax = 4, + + Count, +}; + +constexpr bool IsValidResourceType(LimitableResource type) { + return type < LimitableResource::Count; +} + +class KResourceLimit final : public Object { +public: + KResourceLimit(KernelCore& kernel, Core::System& system); + ~KResourceLimit(); + + s64 GetLimitValue(LimitableResource which) const; + s64 GetCurrentValue(LimitableResource which) const; + s64 GetPeakValue(LimitableResource which) const; + s64 GetFreeValue(LimitableResource which) const; + + ResultCode SetLimitValue(LimitableResource which, s64 value); + + bool Reserve(LimitableResource which, s64 value); + bool Reserve(LimitableResource which, s64 value, s64 timeout); + void Release(LimitableResource which, s64 value); + void Release(LimitableResource which, s64 value, s64 hint); + + std::string GetTypeName() const override { + return "KResourceLimit"; + } + std::string GetName() const override { + return GetTypeName(); + } + + static constexpr HandleType HANDLE_TYPE = HandleType::ResourceLimit; + HandleType GetHandleType() const override { + return HANDLE_TYPE; + } + + virtual void Finalize() override {} + +private: + std::array(LimitableResource::Count)> limit_values{}; + std::array(LimitableResource::Count)> current_values{}; + std::array(LimitableResource::Count)> current_hints{}; + std::array(LimitableResource::Count)> peak_values{}; + mutable KLightLock lock; + s32 waiter_count{}; + KLightConditionVariable cond_var; + KernelCore& kernel; + Core::System& system; +}; +} // namespace Kernel diff --git a/src/core/hle/kernel/k_thread.cpp b/src/core/hle/kernel/k_thread.cpp index aa100e139..38fd8e500 100755 --- a/src/core/hle/kernel/k_thread.cpp +++ b/src/core/hle/kernel/k_thread.cpp @@ -21,6 +21,7 @@ #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_condition_variable.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_thread.h" @@ -29,7 +30,6 @@ #include "core/hle/kernel/memory/memory_layout.h" #include "core/hle/kernel/object.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/svc_results.h" #include "core/hle/kernel/time_manager.h" #include "core/hle/result.h" @@ -247,7 +247,7 @@ void KThread::Finalize() { // Decrement the parent process's thread count. if (parent != nullptr) { parent->DecrementThreadCount(); - parent->GetResourceLimit()->Release(ResourceType::Threads, 1); + parent->GetResourceLimit()->Release(LimitableResource::ThreadCountMax, 1); } } diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp index df309d523..c66a993c2 100755 --- a/src/core/hle/kernel/kernel.cpp +++ b/src/core/hle/kernel/kernel.cpp @@ -28,6 +28,7 @@ #include "core/hle/kernel/client_port.h" #include "core/hle/kernel/errors.h" #include "core/hle/kernel/handle_table.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" @@ -36,7 +37,6 @@ #include "core/hle/kernel/memory/slab_heap.h" #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/service_thread.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/time_manager.h" @@ -66,7 +66,7 @@ struct KernelCore::Impl { is_phantom_mode_for_singlecore = false; InitializePhysicalCores(); - InitializeSystemResourceLimit(kernel); + InitializeSystemResourceLimit(kernel, system); InitializeMemoryLayout(); InitializePreemption(kernel); InitializeSchedulers(); @@ -131,19 +131,23 @@ struct KernelCore::Impl { } // Creates the default system resource limit - void InitializeSystemResourceLimit(KernelCore& kernel) { - system_resource_limit = ResourceLimit::Create(kernel); + void InitializeSystemResourceLimit(KernelCore& kernel, Core::System& system) { + system_resource_limit = std::make_shared(kernel, system); // If setting the default system values fails, then something seriously wrong has occurred. - ASSERT(system_resource_limit->SetLimitValue(ResourceType::PhysicalMemory, 0x100000000) + ASSERT( + system_resource_limit->SetLimitValue(LimitableResource::PhysicalMemoryMax, 0x100000000) + .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 800) + .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700) + .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 200) + .IsSuccess()); + ASSERT(system_resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 900) .IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Threads, 800).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Events, 700).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::TransferMemory, 200).IsSuccess()); - ASSERT(system_resource_limit->SetLimitValue(ResourceType::Sessions, 900).IsSuccess()); - if (!system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0) || - !system_resource_limit->Reserve(ResourceType::PhysicalMemory, 0x60000)) { + if (!system_resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, 0x60000)) { UNREACHABLE(); } } @@ -320,7 +324,7 @@ struct KernelCore::Impl { std::unique_ptr global_scheduler_context; Kernel::TimeManager time_manager; - std::shared_ptr system_resource_limit; + std::shared_ptr system_resource_limit; std::shared_ptr preemption_event; @@ -390,7 +394,7 @@ void KernelCore::Shutdown() { impl->Shutdown(); } -std::shared_ptr KernelCore::GetSystemResourceLimit() const { +std::shared_ptr KernelCore::GetSystemResourceLimit() const { return impl->system_resource_limit; } diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h index e7c77727b..806a0d986 100755 --- a/src/core/hle/kernel/kernel.h +++ b/src/core/hle/kernel/kernel.h @@ -38,7 +38,7 @@ class GlobalSchedulerContext; class HandleTable; class PhysicalCore; class Process; -class ResourceLimit; +class KResourceLimit; class KScheduler; class SharedMemory; class ServiceThread; @@ -85,7 +85,7 @@ public: void Shutdown(); /// Retrieves a shared pointer to the system resource limit instance. - std::shared_ptr GetSystemResourceLimit() const; + std::shared_ptr GetSystemResourceLimit() const; /// Retrieves a shared pointer to a Thread instance within the thread wakeup handle table. std::shared_ptr 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..d8c7d980a 100755 --- a/src/core/hle/kernel/memory/page_table.cpp +++ b/src/core/hle/kernel/memory/page_table.cpp @@ -7,6 +7,7 @@ #include "common/scope_exit.h" #include "core/core.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/kernel.h" #include "core/hle/kernel/memory/address_space_info.h" #include "core/hle/kernel/memory/memory_block.h" @@ -15,7 +16,6 @@ #include "core/hle/kernel/memory/page_table.h" #include "core/hle/kernel/memory/system_control.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/memory.h" namespace Kernel::Memory { @@ -413,8 +413,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { const std::size_t remaining_size{size - mapped_size}; const std::size_t remaining_pages{remaining_size / PageSize}; - if (process->GetResourceLimit() && - !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, remaining_size)) { + if (process->GetResourceLimit() && !process->GetResourceLimit()->Reserve( + LimitableResource::PhysicalMemoryMax, remaining_size)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } @@ -422,7 +422,8 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) { { auto block_guard = detail::ScopeExit([&] { system.Kernel().MemoryManager().Free(page_linked_list, remaining_pages, memory_pool); - process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, remaining_size); + process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, + remaining_size); }); CASCADE_CODE(system.Kernel().MemoryManager().Allocate(page_linked_list, remaining_pages, @@ -474,7 +475,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) { CASCADE_CODE(UnmapMemory(addr, size)); auto process{system.Kernel().CurrentProcess()}; - process->GetResourceLimit()->Release(ResourceType::PhysicalMemory, mapped_size); + process->GetResourceLimit()->Release(LimitableResource::PhysicalMemoryMax, mapped_size); physical_memory_usage -= mapped_size; return RESULT_SUCCESS; @@ -783,7 +784,7 @@ ResultVal PageTable::SetHeapSize(std::size_t size) { auto process{system.Kernel().CurrentProcess()}; if (process->GetResourceLimit() && delta != 0 && - !process->GetResourceLimit()->Reserve(ResourceType::PhysicalMemory, delta)) { + !process->GetResourceLimit()->Reserve(LimitableResource::PhysicalMemoryMax, delta)) { return ERR_RESOURCE_LIMIT_EXCEEDED; } diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index 0edbfc4cc..9efcb95f3 100755 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp @@ -15,6 +15,7 @@ #include "core/file_sys/program_metadata.h" #include "core/hle/kernel/code_set.h" #include "core/hle/kernel/errors.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_thread.h" #include "core/hle/kernel/kernel.h" @@ -22,7 +23,6 @@ #include "core/hle/kernel/memory/page_table.h" #include "core/hle/kernel/memory/slab_heap.h" #include "core/hle/kernel/process.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/lock.h" #include "core/memory.h" #include "core/settings.h" @@ -116,7 +116,7 @@ std::shared_ptr Process::Create(Core::System& system, std::string name, std::shared_ptr process = std::make_shared(system); process->name = std::move(name); - process->resource_limit = ResourceLimit::Create(kernel); + process->resource_limit = std::make_shared(kernel, system); process->status = ProcessStatus::Created; process->program_id = 0; process->process_id = type == ProcessType::KernelInternal ? kernel.CreateNewKernelProcessID() @@ -132,7 +132,7 @@ std::shared_ptr Process::Create(Core::System& system, std::string name, return process; } -std::shared_ptr Process::GetResourceLimit() const { +std::shared_ptr Process::GetResourceLimit() const { return resource_limit; } @@ -154,7 +154,7 @@ void Process::DecrementThreadCount() { } u64 Process::GetTotalPhysicalMemoryAvailable() const { - const u64 capacity{resource_limit->GetCurrentResourceValue(ResourceType::PhysicalMemory) + + const u64 capacity{resource_limit->GetFreeValue(LimitableResource::PhysicalMemoryMax) + page_table->GetTotalHeapSize() + GetSystemResourceSize() + image_size + main_thread_stack_size}; @@ -308,13 +308,13 @@ ResultCode Process::LoadFromMetadata(const FileSys::ProgramMetadata& metadata, // Set initial resource limits resource_limit->SetLimitValue( - ResourceType::PhysicalMemory, + LimitableResource::PhysicalMemoryMax, kernel.MemoryManager().GetSize(Memory::MemoryManager::Pool::Application)); - resource_limit->SetLimitValue(ResourceType::Threads, 608); - resource_limit->SetLimitValue(ResourceType::Events, 700); - resource_limit->SetLimitValue(ResourceType::TransferMemory, 128); - resource_limit->SetLimitValue(ResourceType::Sessions, 894); - ASSERT(resource_limit->Reserve(ResourceType::PhysicalMemory, code_size)); + resource_limit->SetLimitValue(LimitableResource::ThreadCountMax, 608); + resource_limit->SetLimitValue(LimitableResource::EventCountMax, 700); + resource_limit->SetLimitValue(LimitableResource::TransferMemoryCountMax, 128); + resource_limit->SetLimitValue(LimitableResource::SessionCountMax, 894); + ASSERT(resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, code_size)); // Create TLS region tls_region_address = CreateTLSRegion(); @@ -331,8 +331,8 @@ void Process::Run(s32 main_thread_priority, u64 stack_size) { ChangeStatus(ProcessStatus::Running); SetupMainThread(system, *this, main_thread_priority, main_thread_stack_top); - resource_limit->Reserve(ResourceType::Threads, 1); - resource_limit->Reserve(ResourceType::PhysicalMemory, main_thread_stack_size); + resource_limit->Reserve(LimitableResource::ThreadCountMax, 1); + resource_limit->Reserve(LimitableResource::PhysicalMemoryMax, main_thread_stack_size); } void Process::PrepareForTermination() { diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index 26e647743..c8af76ce8 100755 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h @@ -29,7 +29,7 @@ class ProgramMetadata; namespace Kernel { class KernelCore; -class ResourceLimit; +class KResourceLimit; class KThread; class TLSPage; @@ -170,7 +170,7 @@ public: } /// Gets the resource limit descriptor for this process - std::shared_ptr GetResourceLimit() const; + std::shared_ptr GetResourceLimit() const; /// Gets the ideal CPU core ID for this process u8 GetIdealCoreId() const { @@ -402,7 +402,7 @@ private: u32 system_resource_size = 0; /// Resource limit descriptor for this process - std::shared_ptr resource_limit; + std::shared_ptr resource_limit; /// The ideal CPU core for this process, threads are scheduled on this core by default. u8 ideal_core = 0; diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 7fd514e9d..d89873104 100755 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -26,6 +26,7 @@ #include "core/hle/kernel/handle_table.h" #include "core/hle/kernel/k_address_arbiter.h" #include "core/hle/kernel/k_condition_variable.h" +#include "core/hle/kernel/k_resource_limit.h" #include "core/hle/kernel/k_scheduler.h" #include "core/hle/kernel/k_scoped_scheduler_lock_and_sleep.h" #include "core/hle/kernel/k_synchronization_object.h" @@ -37,7 +38,6 @@ #include "core/hle/kernel/physical_core.h" #include "core/hle/kernel/process.h" #include "core/hle/kernel/readable_event.h" -#include "core/hle/kernel/resource_limit.h" #include "core/hle/kernel/shared_memory.h" #include "core/hle/kernel/svc.h" #include "core/hle/kernel/svc_results.h" @@ -141,7 +141,7 @@ enum class ResourceLimitValueType { ResultVal RetrieveResourceLimitValue(Core::System& system, Handle resource_limit, u32 resource_type, ResourceLimitValueType value_type) { std::lock_guard lock{HLE::g_hle_lock}; - const auto type = static_cast(resource_type); + const auto type = static_cast(resource_type); if (!IsValidResourceType(type)) { LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); return ERR_INVALID_ENUM_VALUE; @@ -151,7 +151,7 @@ ResultVal RetrieveResourceLimitValue(Core::System& system, Handle resource_ ASSERT(current_process != nullptr); const auto resource_limit_object = - current_process->GetHandleTable().Get(resource_limit); + current_process->GetHandleTable().Get(resource_limit); if (!resource_limit_object) { LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", resource_limit); @@ -159,10 +159,10 @@ ResultVal RetrieveResourceLimitValue(Core::System& system, Handle resource_ } if (value_type == ResourceLimitValueType::CurrentValue) { - return MakeResult(resource_limit_object->GetCurrentResourceValue(type)); + return MakeResult(resource_limit_object->GetCurrentValue(type)); } - return MakeResult(resource_limit_object->GetMaxResourceValue(type)); + return MakeResult(resource_limit_object->GetLimitValue(type)); } } // Anonymous namespace @@ -312,7 +312,8 @@ static ResultCode ConnectToNamedPort(Core::System& system, Handle* out_handle, return ERR_NOT_FOUND; } - ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(ResourceType::Sessions, 1)); + ASSERT(kernel.CurrentProcess()->GetResourceLimit()->Reserve(LimitableResource::SessionCountMax, + 1)); auto client_port = it->second; @@ -1450,7 +1451,9 @@ static ResultCode CreateThread(Core::System& system, Handle* out_handle, VAddr e Svc::ResultInvalidPriority); R_UNLESS(process.CheckThreadPriority(priority), Svc::ResultInvalidPriority); - ASSERT(process.GetResourceLimit()->Reserve(ResourceType::Threads, 1)); + ASSERT(process.GetResourceLimit()->Reserve(LimitableResource::ThreadCountMax, 1, + system.CoreTiming().GetGlobalTimeNs().count() + + 100000000)); std::shared_ptr thread; { @@ -1972,7 +1975,7 @@ static ResultCode CreateResourceLimit(Core::System& system, Handle* out_handle) LOG_DEBUG(Kernel_SVC, "called"); auto& kernel = system.Kernel(); - auto resource_limit = ResourceLimit::Create(kernel); + auto resource_limit = std::make_shared(kernel, system); auto* const current_process = kernel.CurrentProcess(); ASSERT(current_process != nullptr); @@ -2019,7 +2022,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour LOG_DEBUG(Kernel_SVC, "called. Handle={:08X}, Resource type={}, Value={}", resource_limit, resource_type, value); - const auto type = static_cast(resource_type); + const auto type = static_cast(resource_type); if (!IsValidResourceType(type)) { LOG_ERROR(Kernel_SVC, "Invalid resource limit type: '{}'", resource_type); return ERR_INVALID_ENUM_VALUE; @@ -2029,7 +2032,7 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour ASSERT(current_process != nullptr); auto resource_limit_object = - current_process->GetHandleTable().Get(resource_limit); + current_process->GetHandleTable().Get(resource_limit); if (!resource_limit_object) { LOG_ERROR(Kernel_SVC, "Handle to non-existent resource limit instance used. Handle={:08X}", resource_limit); @@ -2041,8 +2044,8 @@ static ResultCode SetResourceLimitLimitValue(Core::System& system, Handle resour LOG_ERROR( Kernel_SVC, "Attempted to lower resource limit ({}) for category '{}' below its current value ({})", - resource_limit_object->GetMaxResourceValue(type), resource_type, - resource_limit_object->GetCurrentResourceValue(type)); + resource_limit_object->GetLimitValue(type), resource_type, + resource_limit_object->GetCurrentValue(type)); return set_result; } diff --git a/src/core/hle/service/sockets/bsd.cpp b/src/core/hle/service/sockets/bsd.cpp index 22f540914..4ffb00902 100755 --- a/src/core/hle/service/sockets/bsd.cpp +++ b/src/core/hle/service/sockets/bsd.cpp @@ -416,6 +416,16 @@ void BSD::Close(Kernel::HLERequestContext& ctx) { BuildErrnoResponse(ctx, CloseImpl(fd)); } +void BSD::EventFd(Kernel::HLERequestContext& ctx) { + LOG_WARNING(Service, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; + const s32 fd = rp.Pop(); + + LOG_DEBUG(Service, "called. fd={}", fd); + + BuildErrnoResponse(ctx, Errno::SUCCESS); +} + template void BSD::ExecuteWork(Kernel::HLERequestContext& ctx, Work work) { work.Execute(this); @@ -841,7 +851,7 @@ BSD::BSD(Core::System& system_, const char* name) : ServiceFramework{system_, na {28, nullptr, "GetResourceStatistics"}, {29, nullptr, "RecvMMsg"}, {30, nullptr, "SendMMsg"}, - {31, nullptr, "EventFd"}, + {31, &BSD::EventFd, "EventFd"}, {32, nullptr, "RegisterResourceStatisticsName"}, {33, nullptr, "Initialize2"}, }; diff --git a/src/core/hle/service/sockets/bsd.h b/src/core/hle/service/sockets/bsd.h index f5831dd48..1d2df9c61 100755 --- a/src/core/hle/service/sockets/bsd.h +++ b/src/core/hle/service/sockets/bsd.h @@ -136,6 +136,7 @@ private: void SendTo(Kernel::HLERequestContext& ctx); void Write(Kernel::HLERequestContext& ctx); void Close(Kernel::HLERequestContext& ctx); + void EventFd(Kernel::HLERequestContext& ctx); template void ExecuteWork(Kernel::HLERequestContext& ctx, Work work);