Merge pull request #761 from Subv/resource_limits
Core/ResourceLimits: Implemented the basic structure of ResourceLimits.master
commit
ef8d0e9823
@ -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
|
Loading…
Reference in New Issue