mirror of
https://github.com/Atmosphere-NX/Atmosphere
synced 2025-01-05 11:58:00 +00:00
pm: implement correct application thread boosting mechanism
This commit is contained in:
parent
2d0c881ffe
commit
08ad48fbf3
6 changed files with 50 additions and 26 deletions
|
@ -669,8 +669,8 @@ namespace sts::pm::impl {
|
||||||
return resource::BoostSystemMemoryResourceLimit(boost_size);
|
return resource::BoostSystemMemoryResourceLimit(boost_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result BoostSystemThreadResourceLimit() {
|
Result BoostApplicationThreadResourceLimit() {
|
||||||
return resource::BoostSystemThreadResourceLimit();
|
return resource::BoostApplicationThreadResourceLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
Result AtmosphereGetCurrentLimitInfo(u64 *out_cur_val, u64 *out_lim_val, u32 group, u32 resource) {
|
Result AtmosphereGetCurrentLimitInfo(u64 *out_cur_val, u64 *out_lim_val, u32 group, u32 resource) {
|
||||||
|
|
|
@ -54,7 +54,7 @@ namespace sts::pm::impl {
|
||||||
|
|
||||||
/* Resource Limit API. */
|
/* Resource Limit API. */
|
||||||
Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
Result AtmosphereGetCurrentLimitInfo(u64 *out_cur_val, u64 *out_lim_val, u32 group, u32 resource);
|
Result AtmosphereGetCurrentLimitInfo(u64 *out_cur_val, u64 *out_lim_val, u32 group, u32 resource);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ namespace sts::pm::resource {
|
||||||
Handle g_resource_limit_handles[ResourceLimitGroup_Count];
|
Handle g_resource_limit_handles[ResourceLimitGroup_Count];
|
||||||
spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
|
spl::MemoryArrangement g_memory_arrangement = spl::MemoryArrangement_Standard;
|
||||||
u64 g_system_memory_boost_size = 0;
|
u64 g_system_memory_boost_size = 0;
|
||||||
|
u64 g_extra_application_threads_available = 0;
|
||||||
|
|
||||||
u64 g_resource_limits[ResourceLimitGroup_Count][LimitableResource_Count] = {
|
u64 g_resource_limits[ResourceLimitGroup_Count][LimitableResource_Count] = {
|
||||||
[ResourceLimitGroup_System] = {
|
[ResourceLimitGroup_System] = {
|
||||||
|
@ -205,8 +206,25 @@ namespace sts::pm::resource {
|
||||||
g_resource_limits[ResourceLimitGroup_System][LimitableResource_Sessions] += ExtraSystemSessionCount600;
|
g_resource_limits[ResourceLimitGroup_System][LimitableResource_Sessions] += ExtraSystemSessionCount600;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 7.0.0+: Nintendo restricts the number of system threads here, from 0x260 -> 0x60. */
|
/* 7.0.0+: Calculate the number of extra application threads available. */
|
||||||
/* We will not do this. */
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_700) {
|
||||||
|
/* See how many threads we have available. */
|
||||||
|
u64 total_threads_available = 0;
|
||||||
|
R_ASSERT(svcGetResourceLimitLimitValue(&total_threads_available, GetResourceLimitHandle(ResourceLimitGroup_System), LimitableResource_Threads));
|
||||||
|
|
||||||
|
/* See how many threads we're expecting. */
|
||||||
|
const size_t total_threads_allocated = g_resource_limits[ResourceLimitGroup_System][LimitableResource_Threads] -
|
||||||
|
g_resource_limits[ResourceLimitGroup_Application][LimitableResource_Threads] -
|
||||||
|
g_resource_limits[ResourceLimitGroup_Applet][LimitableResource_Threads];
|
||||||
|
|
||||||
|
/* Ensure we don't over-commit threads. */
|
||||||
|
if (total_threads_available < total_threads_allocated) {
|
||||||
|
std::abort();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set number of extra threads. */
|
||||||
|
g_extra_application_threads_available = total_threads_available;
|
||||||
|
}
|
||||||
|
|
||||||
/* Choose and initialize memory arrangement. */
|
/* Choose and initialize memory arrangement. */
|
||||||
if (firmware_version >= FirmwareVersion_600) {
|
if (firmware_version >= FirmwareVersion_600) {
|
||||||
|
@ -248,7 +266,7 @@ namespace sts::pm::resource {
|
||||||
|
|
||||||
/* Actually set resource limits. */
|
/* Actually set resource limits. */
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(g_resource_limit_lock);
|
std::scoped_lock lk(g_resource_limit_lock);
|
||||||
|
|
||||||
for (size_t group = 0; group < ResourceLimitGroup_Count; group++) {
|
for (size_t group = 0; group < ResourceLimitGroup_Count; group++) {
|
||||||
R_ASSERT(SetResourceLimitLimitValues(static_cast<ResourceLimitGroup>(group), g_memory_resource_limits[g_memory_arrangement][group]));
|
R_ASSERT(SetResourceLimitLimitValues(static_cast<ResourceLimitGroup>(group), g_memory_resource_limits[g_memory_arrangement][group]));
|
||||||
|
@ -266,7 +284,7 @@ namespace sts::pm::resource {
|
||||||
|
|
||||||
const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size;
|
const u64 new_app_size = g_memory_resource_limits[g_memory_arrangement][ResourceLimitGroup_Application] - boost_size;
|
||||||
{
|
{
|
||||||
std::scoped_lock<HosMutex> lk(g_resource_limit_lock);
|
std::scoped_lock lk(g_resource_limit_lock);
|
||||||
|
|
||||||
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) {
|
if (GetRuntimeFirmwareVersion() >= FirmwareVersion_500) {
|
||||||
/* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */
|
/* Starting in 5.0.0, PM does not allow for only one of the sets to fail. */
|
||||||
|
@ -294,10 +312,16 @@ namespace sts::pm::resource {
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
Result BoostSystemThreadResourceLimit() {
|
Result BoostApplicationThreadResourceLimit() {
|
||||||
/* Starting in 7.0.0, Nintendo reduces the number of system threads from 0x260 to 0x60, */
|
std::scoped_lock lk(g_resource_limit_lock);
|
||||||
/* Until this command is called to double that amount to 0xC0. */
|
/* Set new limit. */
|
||||||
/* We will simply not reduce the number of system threads available for no reason. */
|
const u64 new_thread_count = g_resource_limits[ResourceLimitGroup_Application][LimitableResource_Threads] + g_extra_application_threads_available;
|
||||||
|
R_TRY(svcSetResourceLimitLimitValue(GetResourceLimitHandle(ResourceLimitGroup_Application), LimitableResource_Threads, new_thread_count));
|
||||||
|
|
||||||
|
/* Record that we did so. */
|
||||||
|
g_resource_limits[ResourceLimitGroup_Application][LimitableResource_Threads] = new_thread_count;
|
||||||
|
g_extra_application_threads_available = 0;
|
||||||
|
|
||||||
return ResultSuccess;
|
return ResultSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ namespace sts::pm::resource {
|
||||||
/* Resource API. */
|
/* Resource API. */
|
||||||
Result InitializeResourceManager();
|
Result InitializeResourceManager();
|
||||||
Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
||||||
Result BoostSystemThreadResourceLimit();
|
Result BoostApplicationThreadResourceLimit();
|
||||||
Handle GetResourceLimitHandle(ResourceLimitGroup group);
|
Handle GetResourceLimitHandle(ResourceLimitGroup group);
|
||||||
Handle GetResourceLimitHandle(const ldr::ProgramInfo *info);
|
Handle GetResourceLimitHandle(const ldr::ProgramInfo *info);
|
||||||
void WaitResourceAvailable(const ldr::ProgramInfo *info);
|
void WaitResourceAvailable(const ldr::ProgramInfo *info);
|
||||||
|
|
|
@ -65,8 +65,8 @@ namespace sts::pm::shell {
|
||||||
return impl::BoostSystemMemoryResourceLimit(boost_size);
|
return impl::BoostSystemMemoryResourceLimit(boost_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
Result ShellServiceBase::BoostSystemThreadResourceLimit() {
|
Result ShellServiceBase::BoostApplicationThreadResourceLimit() {
|
||||||
return impl::BoostSystemThreadResourceLimit();
|
return impl::BoostApplicationThreadResourceLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShellServiceBase::GetBootFinishedEventHandle(Out<CopiedHandle> out) {
|
void ShellServiceBase::GetBootFinishedEventHandle(Out<CopiedHandle> out) {
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace sts::pm::shell {
|
||||||
virtual void NotifyBootFinished();
|
virtual void NotifyBootFinished();
|
||||||
virtual Result GetApplicationProcessIdForShell(Out<u64> out);
|
virtual Result GetApplicationProcessIdForShell(Out<u64> out);
|
||||||
virtual Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
virtual Result BoostSystemMemoryResourceLimit(u64 boost_size);
|
||||||
virtual Result BoostSystemThreadResourceLimit();
|
virtual Result BoostApplicationThreadResourceLimit();
|
||||||
virtual void GetBootFinishedEventHandle(Out<CopiedHandle> out);
|
virtual void GetBootFinishedEventHandle(Out<CopiedHandle> out);
|
||||||
public:
|
public:
|
||||||
DEFINE_SERVICE_DISPATCH_TABLE {
|
DEFINE_SERVICE_DISPATCH_TABLE {
|
||||||
|
@ -55,7 +55,7 @@ namespace sts::pm::shell {
|
||||||
NotifyBootFinished = 5,
|
NotifyBootFinished = 5,
|
||||||
GetApplicationProcessIdForShell = 6,
|
GetApplicationProcessIdForShell = 6,
|
||||||
BoostSystemMemoryResourceLimit = 7,
|
BoostSystemMemoryResourceLimit = 7,
|
||||||
BoostSystemThreadResourceLimit = 8,
|
BoostApplicationThreadResourceLimit = 8,
|
||||||
GetBootFinishedEventHandle = 9,
|
GetBootFinishedEventHandle = 9,
|
||||||
};
|
};
|
||||||
public:
|
public:
|
||||||
|
@ -71,7 +71,7 @@ namespace sts::pm::shell {
|
||||||
MAKE_SERVICE_COMMAND_META(ShellService, BoostSystemMemoryResourceLimit),
|
MAKE_SERVICE_COMMAND_META(ShellService, BoostSystemMemoryResourceLimit),
|
||||||
|
|
||||||
/* 7.0.0-* */
|
/* 7.0.0-* */
|
||||||
MAKE_SERVICE_COMMAND_META(ShellService, BoostSystemThreadResourceLimit, FirmwareVersion_700),
|
MAKE_SERVICE_COMMAND_META(ShellService, BoostApplicationThreadResourceLimit, FirmwareVersion_700),
|
||||||
|
|
||||||
/* 8.0.0-* */
|
/* 8.0.0-* */
|
||||||
MAKE_SERVICE_COMMAND_META(ShellService, GetBootFinishedEventHandle, FirmwareVersion_800),
|
MAKE_SERVICE_COMMAND_META(ShellService, GetBootFinishedEventHandle, FirmwareVersion_800),
|
||||||
|
|
Loading…
Reference in a new issue