Browse Source
Merge pull request #761 from Subv/resource_limits
Merge pull request #761 from Subv/resource_limits
Core/ResourceLimits: Implemented the basic structure of ResourceLimits.pull/15/merge
12 changed files with 341 additions and 14 deletions
-
2src/core/CMakeLists.txt
-
4src/core/hle/function_wrappers.h
-
3src/core/hle/kernel/kernel.cpp
-
3src/core/hle/kernel/kernel.h
-
1src/core/hle/kernel/process.cpp
-
4src/core/hle/kernel/process.h
-
157src/core/hle/kernel/resource_limit.cpp
-
119src/core/hle/kernel/resource_limit.h
-
49src/core/hle/svc.cpp
-
4src/core/loader/3dsx.cpp
-
4src/core/loader/elf.cpp
-
5src/core/loader/ncch.cpp
@ -0,0 +1,157 @@ |
|||||
|
// Copyright 2015 Citra Emulator Project
|
||||
|
// Licensed under GPLv2 or any later version
|
||||
|
// Refer to the license.txt file included.
|
||||
|
|
||||
|
#include <cstring>
|
||||
|
|
||||
|
#include "common/logging/log.h"
|
||||
|
|
||||
|
#include "core/mem_map.h"
|
||||
|
#include "core/hle/kernel/resource_limit.h"
|
||||
|
|
||||
|
namespace Kernel { |
||||
|
|
||||
|
static SharedPtr<ResourceLimit> resource_limits[4]; |
||||
|
|
||||
|
ResourceLimit::ResourceLimit() {} |
||||
|
ResourceLimit::~ResourceLimit() {} |
||||
|
|
||||
|
SharedPtr<ResourceLimit> ResourceLimit::Create(std::string name) { |
||||
|
SharedPtr<ResourceLimit> resource_limit(new ResourceLimit); |
||||
|
|
||||
|
resource_limit->name = std::move(name); |
||||
|
return resource_limit; |
||||
|
} |
||||
|
|
||||
|
SharedPtr<ResourceLimit> ResourceLimit::GetForCategory(ResourceLimitCategory category) { |
||||
|
switch (category) |
||||
|
{ |
||||
|
case ResourceLimitCategory::APPLICATION: |
||||
|
case ResourceLimitCategory::SYS_APPLET: |
||||
|
case ResourceLimitCategory::LIB_APPLET: |
||||
|
case ResourceLimitCategory::OTHER: |
||||
|
return resource_limits[static_cast<u8>(category)]; |
||||
|
default: |
||||
|
LOG_CRITICAL(Kernel, "Unknown resource limit category"); |
||||
|
UNREACHABLE(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
s32 ResourceLimit::GetCurrentResourceValue(u32 resource) const { |
||||
|
switch (resource) { |
||||
|
case COMMIT: |
||||
|
return current_commit; |
||||
|
case THREAD: |
||||
|
return current_threads; |
||||
|
case EVENT: |
||||
|
return current_events; |
||||
|
case MUTEX: |
||||
|
return current_mutexes; |
||||
|
case SEMAPHORE: |
||||
|
return current_semaphores; |
||||
|
case TIMER: |
||||
|
return current_timers; |
||||
|
case SHARED_MEMORY: |
||||
|
return current_shared_mems; |
||||
|
case ADDRESS_ARBITER: |
||||
|
return current_address_arbiters; |
||||
|
case CPU_TIME: |
||||
|
return current_cpu_time; |
||||
|
default: |
||||
|
LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); |
||||
|
UNIMPLEMENTED(); |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
s32 ResourceLimit::GetMaxResourceValue(u32 resource) const { |
||||
|
switch (resource) { |
||||
|
case COMMIT: |
||||
|
return max_commit; |
||||
|
case THREAD: |
||||
|
return max_threads; |
||||
|
case EVENT: |
||||
|
return max_events; |
||||
|
case MUTEX: |
||||
|
return max_mutexes; |
||||
|
case SEMAPHORE: |
||||
|
return max_semaphores; |
||||
|
case TIMER: |
||||
|
return max_timers; |
||||
|
case SHARED_MEMORY: |
||||
|
return max_shared_mems; |
||||
|
case ADDRESS_ARBITER: |
||||
|
return max_address_arbiters; |
||||
|
case CPU_TIME: |
||||
|
return max_cpu_time; |
||||
|
default: |
||||
|
LOG_ERROR(Kernel, "Unknown resource type=%08X", resource); |
||||
|
UNIMPLEMENTED(); |
||||
|
return 0; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
void ResourceLimitsInit() { |
||||
|
// Create the four resource limits that the system uses
|
||||
|
// Create the APPLICATION resource limit
|
||||
|
SharedPtr<ResourceLimit> resource_limit = ResourceLimit::Create("Applications"); |
||||
|
resource_limit->max_priority = 0x18; |
||||
|
resource_limit->max_commit = 0x4000000; |
||||
|
resource_limit->max_threads = 0x20; |
||||
|
resource_limit->max_events = 0x20; |
||||
|
resource_limit->max_mutexes = 0x20; |
||||
|
resource_limit->max_semaphores = 0x8; |
||||
|
resource_limit->max_timers = 0x8; |
||||
|
resource_limit->max_shared_mems = 0x10; |
||||
|
resource_limit->max_address_arbiters = 0x2; |
||||
|
resource_limit->max_cpu_time = 0x1E; |
||||
|
resource_limits[static_cast<u8>(ResourceLimitCategory::APPLICATION)] = resource_limit; |
||||
|
|
||||
|
// Create the SYS_APPLET resource limit
|
||||
|
resource_limit = ResourceLimit::Create("System Applets"); |
||||
|
resource_limit->max_priority = 0x4; |
||||
|
resource_limit->max_commit = 0x5E00000; |
||||
|
resource_limit->max_threads = 0x1D; |
||||
|
resource_limit->max_events = 0xB; |
||||
|
resource_limit->max_mutexes = 0x8; |
||||
|
resource_limit->max_semaphores = 0x4; |
||||
|
resource_limit->max_timers = 0x4; |
||||
|
resource_limit->max_shared_mems = 0x8; |
||||
|
resource_limit->max_address_arbiters = 0x3; |
||||
|
resource_limit->max_cpu_time = 0x2710; |
||||
|
resource_limits[static_cast<u8>(ResourceLimitCategory::SYS_APPLET)] = resource_limit; |
||||
|
|
||||
|
// Create the LIB_APPLET resource limit
|
||||
|
resource_limit = ResourceLimit::Create("Library Applets"); |
||||
|
resource_limit->max_priority = 0x4; |
||||
|
resource_limit->max_commit = 0x600000; |
||||
|
resource_limit->max_threads = 0xE; |
||||
|
resource_limit->max_events = 0x8; |
||||
|
resource_limit->max_mutexes = 0x8; |
||||
|
resource_limit->max_semaphores = 0x4; |
||||
|
resource_limit->max_timers = 0x4; |
||||
|
resource_limit->max_shared_mems = 0x8; |
||||
|
resource_limit->max_address_arbiters = 0x1; |
||||
|
resource_limit->max_cpu_time = 0x2710; |
||||
|
resource_limits[static_cast<u8>(ResourceLimitCategory::LIB_APPLET)] = resource_limit; |
||||
|
|
||||
|
// Create the OTHER resource limit
|
||||
|
resource_limit = ResourceLimit::Create("Others"); |
||||
|
resource_limit->max_priority = 0x4; |
||||
|
resource_limit->max_commit = 0x2180000; |
||||
|
resource_limit->max_threads = 0xE1; |
||||
|
resource_limit->max_events = 0x108; |
||||
|
resource_limit->max_mutexes = 0x25; |
||||
|
resource_limit->max_semaphores = 0x43; |
||||
|
resource_limit->max_timers = 0x2C; |
||||
|
resource_limit->max_shared_mems = 0x1F; |
||||
|
resource_limit->max_address_arbiters = 0x2D; |
||||
|
resource_limit->max_cpu_time = 0x3E8; |
||||
|
resource_limits[static_cast<u8>(ResourceLimitCategory::OTHER)] = resource_limit; |
||||
|
} |
||||
|
|
||||
|
void ResourceLimitsShutdown() { |
||||
|
|
||||
|
} |
||||
|
|
||||
|
} // namespace
|
||||
@ -0,0 +1,119 @@ |
|||||
|
// Copyright 2015 Citra Emulator Project |
||||
|
// Licensed under GPLv2 or any later version |
||||
|
// Refer to the license.txt file included. |
||||
|
|
||||
|
#pragma once |
||||
|
|
||||
|
#include "common/common_types.h" |
||||
|
|
||||
|
#include "core/hle/kernel/kernel.h" |
||||
|
|
||||
|
namespace Kernel { |
||||
|
|
||||
|
enum class ResourceLimitCategory : u8 { |
||||
|
APPLICATION = 0, |
||||
|
SYS_APPLET = 1, |
||||
|
LIB_APPLET = 2, |
||||
|
OTHER = 3 |
||||
|
}; |
||||
|
|
||||
|
enum ResourceTypes { |
||||
|
PRIORITY = 0, |
||||
|
COMMIT = 1, |
||||
|
THREAD = 2, |
||||
|
EVENT = 3, |
||||
|
MUTEX = 4, |
||||
|
SEMAPHORE = 5, |
||||
|
TIMER = 6, |
||||
|
SHARED_MEMORY = 7, |
||||
|
ADDRESS_ARBITER = 8, |
||||
|
CPU_TIME = 9, |
||||
|
}; |
||||
|
|
||||
|
class ResourceLimit final : public Object { |
||||
|
public: |
||||
|
/** |
||||
|
* Creates a resource limit object. |
||||
|
*/ |
||||
|
static SharedPtr<ResourceLimit> Create(std::string name = "Unknown"); |
||||
|
|
||||
|
/** |
||||
|
* Retrieves the resource limit associated with the specified resource limit category. |
||||
|
* @param category The resource limit category |
||||
|
* @returns The resource limit associated with the category |
||||
|
*/ |
||||
|
static SharedPtr<ResourceLimit> GetForCategory(ResourceLimitCategory category); |
||||
|
|
||||
|
std::string GetTypeName() const override { return "ResourceLimit"; } |
||||
|
std::string GetName() const override { return name; } |
||||
|
|
||||
|
static const HandleType HANDLE_TYPE = HandleType::ResourceLimit; |
||||
|
HandleType GetHandleType() const override { return HANDLE_TYPE; } |
||||
|
|
||||
|
/** |
||||
|
* Gets the current value for the specified resource. |
||||
|
* @param resource Requested resource type |
||||
|
* @returns The current value of the resource type |
||||
|
*/ |
||||
|
s32 GetCurrentResourceValue(u32 resource) const; |
||||
|
|
||||
|
/** |
||||
|
* Gets the max value for the specified resource. |
||||
|
* @param resource Requested resource type |
||||
|
* @returns The max value of the resource type |
||||
|
*/ |
||||
|
s32 GetMaxResourceValue(u32 resource) const; |
||||
|
|
||||
|
/// Name of resource limit object. |
||||
|
std::string name; |
||||
|
|
||||
|
/// Max thread priority that a process in this category can create |
||||
|
s32 max_priority = 0; |
||||
|
|
||||
|
/// Max memory that processes in this category can use |
||||
|
s32 max_commit = 0; |
||||
|
|
||||
|
///< Max number of objects that can be collectively created by the processes in this category |
||||
|
s32 max_threads = 0; |
||||
|
s32 max_events = 0; |
||||
|
s32 max_mutexes = 0; |
||||
|
s32 max_semaphores = 0; |
||||
|
s32 max_timers = 0; |
||||
|
s32 max_shared_mems = 0; |
||||
|
s32 max_address_arbiters = 0; |
||||
|
|
||||
|
/// Max CPU time that the processes in this category can utilize |
||||
|
s32 max_cpu_time = 0; |
||||
|
|
||||
|
// TODO(Subv): Increment these in their respective Kernel::T::Create functions, keeping in mind that |
||||
|
// APPLICATION resource limits should not be affected by the objects created by service modules. |
||||
|
// Currently we have no way of distinguishing if a Create was called by the running application, |
||||
|
// or by a service module. Approach this once we have separated the service modules into their own processes |
||||
|
|
||||
|
/// Current memory that the processes in this category are using |
||||
|
s32 current_commit = 0; |
||||
|
|
||||
|
///< Current number of objects among all processes in this category |
||||
|
s32 current_threads = 0; |
||||
|
s32 current_events = 0; |
||||
|
s32 current_mutexes = 0; |
||||
|
s32 current_semaphores = 0; |
||||
|
s32 current_timers = 0; |
||||
|
s32 current_shared_mems = 0; |
||||
|
s32 current_address_arbiters = 0; |
||||
|
|
||||
|
/// Current CPU time that the processes in this category are utilizing |
||||
|
s32 current_cpu_time = 0; |
||||
|
|
||||
|
private: |
||||
|
ResourceLimit(); |
||||
|
~ResourceLimit() override; |
||||
|
}; |
||||
|
|
||||
|
/// Initializes the resource limits |
||||
|
void ResourceLimitsInit(); |
||||
|
|
||||
|
// Destroys the resource limits |
||||
|
void ResourceLimitsShutdown(); |
||||
|
|
||||
|
} // namespace |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue