From dca4f0687a82b75382df9bf04a3f76c4afab56e2 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Thu, 15 Dec 2022 13:22:07 -0600 Subject: kernel: process: Implement GetFreeThreadCount MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Used by Just DanceĀ® 2023 Edition --- src/core/hle/kernel/k_process.cpp | 11 +++++++++++ src/core/hle/kernel/k_process.h | 3 +++ src/core/hle/kernel/svc.cpp | 15 ++++++++++++++- 3 files changed, 28 insertions(+), 1 deletion(-) diff --git a/src/core/hle/kernel/k_process.cpp b/src/core/hle/kernel/k_process.cpp index d1dc62401..a1abf5d68 100644 --- a/src/core/hle/kernel/k_process.cpp +++ b/src/core/hle/kernel/k_process.cpp @@ -285,6 +285,17 @@ void KProcess::UnregisterThread(KThread* thread) { thread_list.remove(thread); } +u64 KProcess::GetFreeThreadCount() const { + if (resource_limit != nullptr) { + const auto current_value = + resource_limit->GetCurrentValue(LimitableResource::ThreadCountMax); + const auto limit_value = resource_limit->GetLimitValue(LimitableResource::ThreadCountMax); + return limit_value - current_value; + } else { + return 0; + } +} + Result KProcess::Reset() { // Lock the process and the scheduler. KScopedLightLock lk(state_lock); diff --git a/src/core/hle/kernel/k_process.h b/src/core/hle/kernel/k_process.h index 2e0cc3d0b..09bf2f1d0 100644 --- a/src/core/hle/kernel/k_process.h +++ b/src/core/hle/kernel/k_process.h @@ -304,6 +304,9 @@ public: /// from this process' thread list. void UnregisterThread(KThread* thread); + /// Retrieves the number of available threads for this process. + u64 GetFreeThreadCount() const; + /// Clears the signaled state of the process if and only if it's signaled. /// /// @pre The process must not be already terminated. If this is called on a diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index e520cab47..9fd7aae81 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -815,8 +815,15 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han // 6.0.0+ TotalPhysicalMemoryAvailableWithoutSystemResource = 21, TotalPhysicalMemoryUsedWithoutSystemResource = 22, + // 10.0.0+ + IsApplication = 23, + // 13.0.0+ + FreeThreadCount = 24, + // 14.0.0+ + IsSvcPermitted = 26, // Homebrew only + MesosphereMeta = 65000, MesosphereCurrentProcess = 65001, }; @@ -840,7 +847,9 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han case GetInfoType::TitleId: case GetInfoType::UserExceptionContextAddr: case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: - case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: { + case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: + case GetInfoType::IsApplication: + case GetInfoType::FreeThreadCount: { if (info_sub_id != 0) { LOG_ERROR(Kernel_SVC, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id, info_sub_id); @@ -929,6 +938,10 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); return ResultSuccess; + case GetInfoType::FreeThreadCount: + *result = process->GetFreeThreadCount(); + return ResultSuccess; + default: break; } -- cgit v1.2.3 From 20cbf6f3db4f2873f0122aa45f65a0a410978199 Mon Sep 17 00:00:00 2001 From: Narr the Reg Date: Thu, 15 Dec 2022 13:52:25 -0600 Subject: kernel: svc: Fix duplicated InfoType enum --- src/core/hle/kernel/svc.cpp | 137 +++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 90 deletions(-) diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9fd7aae81..788ee2160 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp @@ -784,72 +784,29 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han LOG_TRACE(Kernel_SVC, "called info_id=0x{:X}, info_sub_id=0x{:X}, handle=0x{:08X}", info_id, info_sub_id, handle); - enum class GetInfoType : u64 { - // 1.0.0+ - AllowedCPUCoreMask = 0, - AllowedThreadPriorityMask = 1, - MapRegionBaseAddr = 2, - MapRegionSize = 3, - HeapRegionBaseAddr = 4, - HeapRegionSize = 5, - TotalPhysicalMemoryAvailable = 6, - TotalPhysicalMemoryUsed = 7, - IsCurrentProcessBeingDebugged = 8, - RegisterResourceLimit = 9, - IdleTickCount = 10, - RandomEntropy = 11, - ThreadTickCount = 0xF0000002, - // 2.0.0+ - ASLRRegionBaseAddr = 12, - ASLRRegionSize = 13, - StackRegionBaseAddr = 14, - StackRegionSize = 15, - // 3.0.0+ - SystemResourceSize = 16, - SystemResourceUsage = 17, - TitleId = 18, - // 4.0.0+ - PrivilegedProcessId = 19, - // 5.0.0+ - UserExceptionContextAddr = 20, - // 6.0.0+ - TotalPhysicalMemoryAvailableWithoutSystemResource = 21, - TotalPhysicalMemoryUsedWithoutSystemResource = 22, - // 10.0.0+ - IsApplication = 23, - // 13.0.0+ - FreeThreadCount = 24, - // 14.0.0+ - IsSvcPermitted = 26, - - // Homebrew only - MesosphereMeta = 65000, - MesosphereCurrentProcess = 65001, - }; - - const auto info_id_type = static_cast(info_id); + const auto info_id_type = static_cast(info_id); switch (info_id_type) { - case GetInfoType::AllowedCPUCoreMask: - case GetInfoType::AllowedThreadPriorityMask: - case GetInfoType::MapRegionBaseAddr: - case GetInfoType::MapRegionSize: - case GetInfoType::HeapRegionBaseAddr: - case GetInfoType::HeapRegionSize: - case GetInfoType::ASLRRegionBaseAddr: - case GetInfoType::ASLRRegionSize: - case GetInfoType::StackRegionBaseAddr: - case GetInfoType::StackRegionSize: - case GetInfoType::TotalPhysicalMemoryAvailable: - case GetInfoType::TotalPhysicalMemoryUsed: - case GetInfoType::SystemResourceSize: - case GetInfoType::SystemResourceUsage: - case GetInfoType::TitleId: - case GetInfoType::UserExceptionContextAddr: - case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: - case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: - case GetInfoType::IsApplication: - case GetInfoType::FreeThreadCount: { + case InfoType::CoreMask: + case InfoType::PriorityMask: + case InfoType::AliasRegionAddress: + case InfoType::AliasRegionSize: + case InfoType::HeapRegionAddress: + case InfoType::HeapRegionSize: + case InfoType::AslrRegionAddress: + case InfoType::AslrRegionSize: + case InfoType::StackRegionAddress: + case InfoType::StackRegionSize: + case InfoType::TotalMemorySize: + case InfoType::UsedMemorySize: + case InfoType::SystemResourceSizeTotal: + case InfoType::SystemResourceSizeUsed: + case InfoType::ProgramId: + case InfoType::UserExceptionContextAddress: + case InfoType::TotalNonSystemMemorySize: + case InfoType::UsedNonSystemMemorySize: + case InfoType::IsApplication: + case InfoType::FreeThreadCount: { if (info_sub_id != 0) { LOG_ERROR(Kernel_SVC, "Info sub id is non zero! info_id={}, info_sub_id={}", info_id, info_sub_id); @@ -865,80 +822,80 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han } switch (info_id_type) { - case GetInfoType::AllowedCPUCoreMask: + case InfoType::CoreMask: *result = process->GetCoreMask(); return ResultSuccess; - case GetInfoType::AllowedThreadPriorityMask: + case InfoType::PriorityMask: *result = process->GetPriorityMask(); return ResultSuccess; - case GetInfoType::MapRegionBaseAddr: + case InfoType::AliasRegionAddress: *result = process->PageTable().GetAliasRegionStart(); return ResultSuccess; - case GetInfoType::MapRegionSize: + case InfoType::AliasRegionSize: *result = process->PageTable().GetAliasRegionSize(); return ResultSuccess; - case GetInfoType::HeapRegionBaseAddr: + case InfoType::HeapRegionAddress: *result = process->PageTable().GetHeapRegionStart(); return ResultSuccess; - case GetInfoType::HeapRegionSize: + case InfoType::HeapRegionSize: *result = process->PageTable().GetHeapRegionSize(); return ResultSuccess; - case GetInfoType::ASLRRegionBaseAddr: + case InfoType::AslrRegionAddress: *result = process->PageTable().GetAliasCodeRegionStart(); return ResultSuccess; - case GetInfoType::ASLRRegionSize: + case InfoType::AslrRegionSize: *result = process->PageTable().GetAliasCodeRegionSize(); return ResultSuccess; - case GetInfoType::StackRegionBaseAddr: + case InfoType::StackRegionAddress: *result = process->PageTable().GetStackRegionStart(); return ResultSuccess; - case GetInfoType::StackRegionSize: + case InfoType::StackRegionSize: *result = process->PageTable().GetStackRegionSize(); return ResultSuccess; - case GetInfoType::TotalPhysicalMemoryAvailable: + case InfoType::TotalMemorySize: *result = process->GetTotalPhysicalMemoryAvailable(); return ResultSuccess; - case GetInfoType::TotalPhysicalMemoryUsed: + case InfoType::UsedMemorySize: *result = process->GetTotalPhysicalMemoryUsed(); return ResultSuccess; - case GetInfoType::SystemResourceSize: + case InfoType::SystemResourceSizeTotal: *result = process->GetSystemResourceSize(); return ResultSuccess; - case GetInfoType::SystemResourceUsage: + case InfoType::SystemResourceSizeUsed: LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query system resource usage"); *result = process->GetSystemResourceUsage(); return ResultSuccess; - case GetInfoType::TitleId: + case InfoType::ProgramId: *result = process->GetProgramID(); return ResultSuccess; - case GetInfoType::UserExceptionContextAddr: + case InfoType::UserExceptionContextAddress: *result = process->GetProcessLocalRegionAddress(); return ResultSuccess; - case GetInfoType::TotalPhysicalMemoryAvailableWithoutSystemResource: + case InfoType::TotalNonSystemMemorySize: *result = process->GetTotalPhysicalMemoryAvailableWithoutSystemResource(); return ResultSuccess; - case GetInfoType::TotalPhysicalMemoryUsedWithoutSystemResource: + case InfoType::UsedNonSystemMemorySize: *result = process->GetTotalPhysicalMemoryUsedWithoutSystemResource(); return ResultSuccess; - case GetInfoType::FreeThreadCount: + case InfoType::FreeThreadCount: *result = process->GetFreeThreadCount(); return ResultSuccess; @@ -950,11 +907,11 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han return ResultInvalidEnumValue; } - case GetInfoType::IsCurrentProcessBeingDebugged: + case InfoType::DebuggerAttached: *result = 0; return ResultSuccess; - case GetInfoType::RegisterResourceLimit: { + case InfoType::ResourceLimit: { if (handle != 0) { LOG_ERROR(Kernel, "Handle is non zero! handle={:08X}", handle); return ResultInvalidHandle; @@ -982,7 +939,7 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han return ResultSuccess; } - case GetInfoType::RandomEntropy: + case InfoType::RandomEntropy: if (handle != 0) { LOG_ERROR(Kernel_SVC, "Process Handle is non zero, expected 0 result but got {:016X}", handle); @@ -998,13 +955,13 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han *result = system.Kernel().CurrentProcess()->GetRandomEntropy(info_sub_id); return ResultSuccess; - case GetInfoType::PrivilegedProcessId: + case InfoType::InitialProcessIdRange: LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query privileged process id bounds, returned 0"); *result = 0; return ResultSuccess; - case GetInfoType::ThreadTickCount: { + case InfoType::ThreadTickCount: { constexpr u64 num_cpus = 4; if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id >= num_cpus) { LOG_ERROR(Kernel_SVC, "Core count is out of range, expected {} but got {}", num_cpus, @@ -1039,7 +996,7 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han *result = out_ticks; return ResultSuccess; } - case GetInfoType::IdleTickCount: { + case InfoType::IdleTickCount: { // Verify the input handle is invalid. R_UNLESS(handle == InvalidHandle, ResultInvalidHandle); @@ -1053,7 +1010,7 @@ static Result GetInfo(Core::System& system, u64* result, u64 info_id, Handle han *result = system.Kernel().CurrentScheduler()->GetIdleThread()->GetCpuTime(); return ResultSuccess; } - case GetInfoType::MesosphereCurrentProcess: { + case InfoType::MesosphereCurrentProcess: { // Verify the input handle is invalid. R_UNLESS(handle == InvalidHandle, ResultInvalidHandle); -- cgit v1.2.3