Fix Circular Queue Destructor + Memory Infos + Improve Priority Documentation

This commit is contained in:
◱ PixelyIon 2020-11-21 20:55:57 +05:30 committed by ◱ PixelyIon
parent 7167393e3c
commit a3dd759a1c
7 changed files with 34 additions and 33 deletions

View File

@ -21,19 +21,14 @@ namespace skyline {
std::condition_variable produceCondition;
public:
inline CircularQueue(size_t size) : vector(size * sizeof(Type)) {}
inline CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
inline ~CircularQueue() {
ssize_t size{};
if (start < end)
size = end - start;
else
size = (reinterpret_cast<Type *>(vector.end().base()) - start) + (end - reinterpret_cast<Type *>(vector.begin().base()));
while (size--) {
std::destroy_at(start);
if (start + 1 == reinterpret_cast<Type *>(vector.end().base()))
start = reinterpret_cast<Type *>(vector.begin().base());
while (start != end) {
auto next{start + 1};
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
std::destroy_at(next);
start = next;
}
}

View File

@ -195,18 +195,18 @@ namespace skyline::kernel {
return std::nullopt;
}
size_t MemoryManager::GetMemoryUsage() {
size_t MemoryManager::GetUserMemoryUsage() {
std::shared_lock lock(mutex);
size_t size{};
for (const auto &chunk : chunks)
if (chunk.state != memory::states::Unmapped && chunk.state != memory::states::Reserved)
if (chunk.state == memory::states::Heap)
size += chunk.size;
return size;
return size + code.size + state.process->mainThreadStack->size;
}
size_t MemoryManager::GetKMemoryBlockSize() {
size_t MemoryManager::GetSystemResourceUsage() {
std::shared_lock lock(mutex);
constexpr size_t KMemoryBlockSize{0x40};
return util::AlignUp(chunks.size() * KMemoryBlockSize, PAGE_SIZE);
return std::min(static_cast<size_t>(state.process->npdm.meta.systemResourceSize), util::AlignUp(chunks.size() * KMemoryBlockSize, PAGE_SIZE));
}
}

View File

@ -240,14 +240,15 @@ namespace skyline {
std::optional<ChunkDescriptor> Get(void *ptr);
/**
* @return The cumulative size of all memory mappings in bytes
* @return The cumulative size of all heap (Physical Memory + Process Heap) memory mappings, the code region and the main thread stack in bytes
*/
size_t GetMemoryUsage();
size_t GetUserMemoryUsage();
/**
* @return The total page-aligned size used to store memory block metadata, if they were KMemoryBlocks rather than ChunkDescriptor
* @note There is a ceiling of SystemResourceSize as specified in the NPDM, this value will be clipped to that
*/
size_t GetKMemoryBlockSize();
size_t GetSystemResourceUsage();
};
}
}

View File

@ -13,15 +13,19 @@ namespace skyline {
namespace kernel {
using CoreMask = std::bitset<constant::CoreCount>;
/**
* @brief Priority on HOS determines scheduling behavior relative to other threads
* @note Lower priority values result in a higher priority, similar to niceness on Linux
*/
struct Priority {
u8 min;
u8 max;
u8 min; //!< Numerically lowest priority, highest scheduler priority
u8 max; //!< Numerically highest priority, lowest scheduler priority
/**
* @return A bitmask with each bit corresponding to if scheduler priority with the same index is valid
*/
constexpr u64 Mask() const {
u64 mask{};
for (u8 i{min}; i <= max; i++)
mask |= 1 << i;
return mask;
return (std::numeric_limits<u64>::max() >> ((std::numeric_limits<u64>::digits - 1 + min) - max)) << min;
}
constexpr bool Valid(i8 value) const {

View File

@ -367,7 +367,7 @@ namespace skyline::kernel::svc {
}
auto processMask{state.process->npdm.threadInfo.coreMask};
if ((processMask | affinityMask) == processMask) {
if ((processMask | affinityMask) != processMask) {
state.logger->Warn("svcSetThreadCoreMask: 'affinityMask' invalid: {} (Process Mask: {})", affinityMask, processMask);
state.ctx->gpr.w0 = result::InvalidCoreId;
return;
@ -790,11 +790,11 @@ namespace skyline::kernel::svc {
break;
case InfoState::TotalMemoryAvailable:
out = totalPhysicalMemory;
out = std::min(totalPhysicalMemory, state.process->memory.heap.size);
break;
case InfoState::TotalMemoryUsage:
out = state.process->memory.GetMemoryUsage() + state.process->memory.GetKMemoryBlockSize();
out = state.process->memory.GetUserMemoryUsage() + state.process->memory.GetSystemResourceUsage();
break;
case InfoState::RandomEntropy:
@ -823,7 +823,7 @@ namespace skyline::kernel::svc {
case InfoState::TotalSystemResourceUsage:
// A very rough approximation of what this should be on the Switch, the amount of memory allocated for storing the memory blocks (https://switchbrew.org/wiki/Kernel_objects#KMemoryBlockManager)
out = std::min(static_cast<size_t>(state.process->npdm.meta.systemResourceSize), state.process->memory.GetKMemoryBlockSize());
out = state.process->memory.GetSystemResourceUsage();
break;
case InfoState::ProgramId:
@ -831,11 +831,11 @@ namespace skyline::kernel::svc {
break;
case InfoState::TotalMemoryAvailableWithoutSystemResource:
out = totalPhysicalMemory - state.process->npdm.meta.systemResourceSize;
out = std::min(totalPhysicalMemory, state.process->memory.heap.size) - state.process->npdm.meta.systemResourceSize;
break;
case InfoState::TotalMemoryUsageWithoutSystemResource:
out = state.process->memory.GetMemoryUsage(); // Our regular estimates don't contain the system resources
out = state.process->memory.GetUserMemoryUsage();
break;
case InfoState::UserExceptionContextAddr:

View File

@ -54,7 +54,7 @@ namespace skyline::vfs {
auto trailingOnes{__builtin_ctz(~capability.raw)};
switch (trailingOnes) {
case 3:
threadInfo.priority = kernel::Priority{capability.threadInfo.lowestPriority, capability.threadInfo.highestPriority};
threadInfo.priority = kernel::Priority{capability.threadInfo.highestPriority, capability.threadInfo.lowestPriority};
threadInfo.coreMask = {};
for (u8 core{capability.threadInfo.minCoreId}; core <= capability.threadInfo.maxCoreId; core++)

View File

@ -81,11 +81,12 @@ namespace skyline {
union __attribute__((packed)) NpdmKernelCapability {
/**
* @url https://switchbrew.org/wiki/NPDM#ThreadInfo
* @note Priority field names are based on real scheduler priority (Lower value is higher priority)
*/
struct __attribute__((packed)) {
u8 pattern : 4; //!< 0b0111
u8 highestPriority : 6;
u8 lowestPriority : 6;
u8 highestPriority : 6;
u8 minCoreId : 8;
u8 maxCoreId : 8;
} threadInfo;