mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-12-23 14:21: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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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:
|
||||
|
@ -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++)
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user