mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 17:51:52 +01:00
Fix Circular Queue Destructor + Memory Infos + Improve Priority Documentation
This commit is contained in:
parent
7167393e3c
commit
a3dd759a1c
@ -21,19 +21,14 @@ namespace skyline {
|
|||||||
std::condition_variable produceCondition;
|
std::condition_variable produceCondition;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline CircularQueue(size_t size) : vector(size * sizeof(Type)) {}
|
inline CircularQueue(size_t size) : vector((size + 1) * sizeof(Type)) {}
|
||||||
|
|
||||||
inline ~CircularQueue() {
|
inline ~CircularQueue() {
|
||||||
ssize_t size{};
|
while (start != end) {
|
||||||
if (start < end)
|
auto next{start + 1};
|
||||||
size = end - start;
|
next = (next == reinterpret_cast<Type *>(vector.end().base())) ? reinterpret_cast<Type *>(vector.begin().base()) : next;
|
||||||
else
|
std::destroy_at(next);
|
||||||
size = (reinterpret_cast<Type *>(vector.end().base()) - start) + (end - reinterpret_cast<Type *>(vector.begin().base()));
|
start = next;
|
||||||
|
|
||||||
while (size--) {
|
|
||||||
std::destroy_at(start);
|
|
||||||
if (start + 1 == reinterpret_cast<Type *>(vector.end().base()))
|
|
||||||
start = reinterpret_cast<Type *>(vector.begin().base());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,18 +195,18 @@ namespace skyline::kernel {
|
|||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t MemoryManager::GetMemoryUsage() {
|
size_t MemoryManager::GetUserMemoryUsage() {
|
||||||
std::shared_lock lock(mutex);
|
std::shared_lock lock(mutex);
|
||||||
size_t size{};
|
size_t size{};
|
||||||
for (const auto &chunk : chunks)
|
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;
|
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);
|
std::shared_lock lock(mutex);
|
||||||
constexpr size_t KMemoryBlockSize{0x40};
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -240,14 +240,15 @@ namespace skyline {
|
|||||||
std::optional<ChunkDescriptor> Get(void *ptr);
|
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
|
* @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();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,15 +13,19 @@ namespace skyline {
|
|||||||
namespace kernel {
|
namespace kernel {
|
||||||
using CoreMask = std::bitset<constant::CoreCount>;
|
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 {
|
struct Priority {
|
||||||
u8 min;
|
u8 min; //!< Numerically lowest priority, highest scheduler priority
|
||||||
u8 max;
|
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 {
|
constexpr u64 Mask() const {
|
||||||
u64 mask{};
|
return (std::numeric_limits<u64>::max() >> ((std::numeric_limits<u64>::digits - 1 + min) - max)) << min;
|
||||||
for (u8 i{min}; i <= max; i++)
|
|
||||||
mask |= 1 << i;
|
|
||||||
return mask;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constexpr bool Valid(i8 value) const {
|
constexpr bool Valid(i8 value) const {
|
||||||
|
@ -367,7 +367,7 @@ namespace skyline::kernel::svc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto processMask{state.process->npdm.threadInfo.coreMask};
|
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.logger->Warn("svcSetThreadCoreMask: 'affinityMask' invalid: {} (Process Mask: {})", affinityMask, processMask);
|
||||||
state.ctx->gpr.w0 = result::InvalidCoreId;
|
state.ctx->gpr.w0 = result::InvalidCoreId;
|
||||||
return;
|
return;
|
||||||
@ -790,11 +790,11 @@ namespace skyline::kernel::svc {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case InfoState::TotalMemoryAvailable:
|
case InfoState::TotalMemoryAvailable:
|
||||||
out = totalPhysicalMemory;
|
out = std::min(totalPhysicalMemory, state.process->memory.heap.size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InfoState::TotalMemoryUsage:
|
case InfoState::TotalMemoryUsage:
|
||||||
out = state.process->memory.GetMemoryUsage() + state.process->memory.GetKMemoryBlockSize();
|
out = state.process->memory.GetUserMemoryUsage() + state.process->memory.GetSystemResourceUsage();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InfoState::RandomEntropy:
|
case InfoState::RandomEntropy:
|
||||||
@ -823,7 +823,7 @@ namespace skyline::kernel::svc {
|
|||||||
|
|
||||||
case InfoState::TotalSystemResourceUsage:
|
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)
|
// 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;
|
break;
|
||||||
|
|
||||||
case InfoState::ProgramId:
|
case InfoState::ProgramId:
|
||||||
@ -831,11 +831,11 @@ namespace skyline::kernel::svc {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case InfoState::TotalMemoryAvailableWithoutSystemResource:
|
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;
|
break;
|
||||||
|
|
||||||
case InfoState::TotalMemoryUsageWithoutSystemResource:
|
case InfoState::TotalMemoryUsageWithoutSystemResource:
|
||||||
out = state.process->memory.GetMemoryUsage(); // Our regular estimates don't contain the system resources
|
out = state.process->memory.GetUserMemoryUsage();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case InfoState::UserExceptionContextAddr:
|
case InfoState::UserExceptionContextAddr:
|
||||||
|
@ -54,7 +54,7 @@ namespace skyline::vfs {
|
|||||||
auto trailingOnes{__builtin_ctz(~capability.raw)};
|
auto trailingOnes{__builtin_ctz(~capability.raw)};
|
||||||
switch (trailingOnes) {
|
switch (trailingOnes) {
|
||||||
case 3:
|
case 3:
|
||||||
threadInfo.priority = kernel::Priority{capability.threadInfo.lowestPriority, capability.threadInfo.highestPriority};
|
threadInfo.priority = kernel::Priority{capability.threadInfo.highestPriority, capability.threadInfo.lowestPriority};
|
||||||
|
|
||||||
threadInfo.coreMask = {};
|
threadInfo.coreMask = {};
|
||||||
for (u8 core{capability.threadInfo.minCoreId}; core <= capability.threadInfo.maxCoreId; core++)
|
for (u8 core{capability.threadInfo.minCoreId}; core <= capability.threadInfo.maxCoreId; core++)
|
||||||
|
@ -81,11 +81,12 @@ namespace skyline {
|
|||||||
union __attribute__((packed)) NpdmKernelCapability {
|
union __attribute__((packed)) NpdmKernelCapability {
|
||||||
/**
|
/**
|
||||||
* @url https://switchbrew.org/wiki/NPDM#ThreadInfo
|
* @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)) {
|
struct __attribute__((packed)) {
|
||||||
u8 pattern : 4; //!< 0b0111
|
u8 pattern : 4; //!< 0b0111
|
||||||
u8 highestPriority : 6;
|
|
||||||
u8 lowestPriority : 6;
|
u8 lowestPriority : 6;
|
||||||
|
u8 highestPriority : 6;
|
||||||
u8 minCoreId : 8;
|
u8 minCoreId : 8;
|
||||||
u8 maxCoreId : 8;
|
u8 maxCoreId : 8;
|
||||||
} threadInfo;
|
} threadInfo;
|
||||||
|
Loading…
Reference in New Issue
Block a user