early-access version 1346

This commit is contained in:
pineappleEA
2021-01-21 02:42:22 +01:00
parent d92b7506c2
commit f7882f96ec
71 changed files with 2999 additions and 722 deletions

View File

@@ -41,6 +41,9 @@ std::size_t MemoryManager::Impl::Initialize(Pool new_pool, u64 start_address, u6
return total_metadata_size;
}
MemoryManager::MemoryManager(KernelCore& kernel)
: pool_lock_0{kernel}, pool_lock_1{kernel}, pool_lock_2{kernel}, pool_lock_3{kernel} {}
void MemoryManager::InitializeManager(Pool pool, u64 start_address, u64 end_address) {
ASSERT(pool < Pool::Count);
managers[static_cast<std::size_t>(pool)].Initialize(pool, start_address, end_address);
@@ -55,7 +58,7 @@ VAddr MemoryManager::AllocateContinuous(std::size_t num_pages, std::size_t align
// Lock the pool that we're allocating from
const auto pool_index{static_cast<std::size_t>(pool)};
std::lock_guard lock{pool_locks[pool_index]};
KScopedLightLock lk{PoolLock(pool_index)};
// Choose a heap based on our page size request
const s32 heap_index{PageHeap::GetAlignedBlockIndex(num_pages, align_pages)};
@@ -90,7 +93,7 @@ ResultCode MemoryManager::Allocate(PageLinkedList& page_list, std::size_t num_pa
// Lock the pool that we're allocating from
const auto pool_index{static_cast<std::size_t>(pool)};
std::lock_guard lock{pool_locks[pool_index]};
KScopedLightLock lk{PoolLock(pool_index)};
// Choose a heap based on our page size request
const s32 heap_index{PageHeap::GetBlockIndex(num_pages)};
@@ -157,7 +160,7 @@ ResultCode MemoryManager::Free(PageLinkedList& page_list, std::size_t num_pages,
// Lock the pool that we're freeing from
const auto pool_index{static_cast<std::size_t>(pool)};
std::lock_guard lock{pool_locks[pool_index]};
KScopedLightLock lk{PoolLock(pool_index)};
// TODO (bunnei): Support multiple managers
Impl& chosen_manager{managers[pool_index]};

View File

@@ -7,10 +7,16 @@
#include <array>
#include <mutex>
#include "common/assert.h"
#include "common/common_types.h"
#include "core/hle/kernel/k_light_lock.h"
#include "core/hle/kernel/memory/page_heap.h"
#include "core/hle/result.h"
namespace Kernel {
class KernelCore;
}
namespace Kernel::Memory {
class PageLinkedList;
@@ -37,7 +43,7 @@ public:
Mask = (0xF << Shift),
};
MemoryManager() = default;
MemoryManager(KernelCore& kernel);
constexpr std::size_t GetSize(Pool pool) const {
return managers[static_cast<std::size_t>(pool)].GetSize();
@@ -89,7 +95,24 @@ private:
};
private:
std::array<std::mutex, static_cast<std::size_t>(Pool::Count)> pool_locks;
KLightLock pool_lock_0;
KLightLock pool_lock_1;
KLightLock pool_lock_2;
KLightLock pool_lock_3;
KLightLock& PoolLock(std::size_t index) {
switch (index) {
case 0:
return pool_lock_0;
case 1:
return pool_lock_1;
case 2:
return pool_lock_2;
}
ASSERT(index == 3);
return pool_lock_3;
}
std::array<Impl, MaxManagerCount> managers;
};

View File

@@ -57,7 +57,7 @@ constexpr std::size_t GetSizeInRange(const MemoryInfo& info, VAddr start, VAddr
} // namespace
PageTable::PageTable(Core::System& system) : system{system} {}
PageTable::PageTable(Core::System& system) : general_lock{system.Kernel()}, system{system} {}
ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_type,
bool enable_aslr, VAddr code_addr, std::size_t code_size,
@@ -272,7 +272,7 @@ ResultCode PageTable::InitializeForProcess(FileSys::ProgramAddressSpaceType as_t
ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemoryState state,
MemoryPermission perm) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const u64 size{num_pages * PageSize};
@@ -295,7 +295,7 @@ ResultCode PageTable::MapProcessCode(VAddr addr, std::size_t num_pages, MemorySt
}
ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const std::size_t num_pages{size / PageSize};
@@ -332,7 +332,7 @@ ResultCode PageTable::MapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::
}
ResultCode PageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
if (!size) {
return RESULT_SUCCESS;
@@ -394,7 +394,7 @@ void PageTable::MapPhysicalMemory(PageLinkedList& page_linked_list, VAddr start,
}
ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
std::size_t mapped_size{};
const VAddr end_addr{addr + size};
@@ -444,7 +444,7 @@ ResultCode PageTable::MapPhysicalMemory(VAddr addr, std::size_t size) {
}
ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const VAddr end_addr{addr + size};
ResultCode result{RESULT_SUCCESS};
@@ -481,7 +481,7 @@ ResultCode PageTable::UnmapPhysicalMemory(VAddr addr, std::size_t size) {
}
ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const VAddr end_addr{addr + size};
ResultCode result{RESULT_SUCCESS};
@@ -517,7 +517,7 @@ ResultCode PageTable::UnmapMemory(VAddr addr, std::size_t size) {
}
ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState src_state{};
CASCADE_CODE(CheckMemoryState(
@@ -555,7 +555,7 @@ ResultCode PageTable::Map(VAddr dst_addr, VAddr src_addr, std::size_t size) {
}
ResultCode PageTable::Unmap(VAddr dst_addr, VAddr src_addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState src_state{};
CASCADE_CODE(CheckMemoryState(
@@ -620,7 +620,7 @@ ResultCode PageTable::MapPages(VAddr addr, const PageLinkedList& page_linked_lis
ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, MemoryState state,
MemoryPermission perm) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const std::size_t num_pages{page_linked_list.GetNumPages()};
const std::size_t size{num_pages * PageSize};
@@ -642,7 +642,7 @@ ResultCode PageTable::MapPages(VAddr addr, PageLinkedList& page_linked_list, Mem
ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, MemoryPermission perm) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState prev_state{};
MemoryPermission prev_perm{};
@@ -688,7 +688,7 @@ ResultCode PageTable::SetCodeMemoryPermission(VAddr addr, std::size_t size, Memo
}
MemoryInfo PageTable::QueryInfoImpl(VAddr addr) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
return block_manager->FindBlock(addr).GetMemoryInfo();
}
@@ -703,7 +703,7 @@ MemoryInfo PageTable::QueryInfo(VAddr addr) {
}
ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, MemoryPermission perm) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState state{};
MemoryAttribute attribute{};
@@ -721,7 +721,7 @@ ResultCode PageTable::ReserveTransferMemory(VAddr addr, std::size_t size, Memory
}
ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState state{};
@@ -739,7 +739,7 @@ ResultCode PageTable::ResetTransferMemory(VAddr addr, std::size_t size) {
ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAttribute mask,
MemoryAttribute value) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryState state{};
MemoryPermission perm{};
@@ -760,7 +760,7 @@ ResultCode PageTable::SetMemoryAttribute(VAddr addr, std::size_t size, MemoryAtt
}
ResultCode PageTable::SetHeapCapacity(std::size_t new_heap_capacity) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
heap_capacity = new_heap_capacity;
return RESULT_SUCCESS;
}
@@ -777,7 +777,7 @@ ResultVal<VAddr> PageTable::SetHeapSize(std::size_t size) {
// Increase the heap size
{
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
const u64 delta{size - previous_heap_size};
@@ -813,7 +813,7 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
bool is_map_only, VAddr region_start,
std::size_t region_num_pages, MemoryState state,
MemoryPermission perm, PAddr map_addr) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
if (!CanContain(region_start, region_num_pages * PageSize, state)) {
return ERR_INVALID_ADDRESS_STATE;
@@ -844,7 +844,7 @@ ResultVal<VAddr> PageTable::AllocateAndMapMemory(std::size_t needed_num_pages, s
}
ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryPermission perm{};
if (const ResultCode result{CheckMemoryState(
@@ -867,7 +867,7 @@ ResultCode PageTable::LockForDeviceAddressSpace(VAddr addr, std::size_t size) {
}
ResultCode PageTable::UnlockForDeviceAddressSpace(VAddr addr, std::size_t size) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
MemoryPermission perm{};
if (const ResultCode result{CheckMemoryState(
@@ -937,7 +937,7 @@ VAddr PageTable::AllocateVirtualMemory(VAddr start, std::size_t region_num_pages
ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinkedList& page_group,
OperationType operation) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
ASSERT(Common::IsAligned(addr, PageSize));
ASSERT(num_pages > 0);
@@ -962,7 +962,7 @@ ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, const PageLinke
ResultCode PageTable::Operate(VAddr addr, std::size_t num_pages, MemoryPermission perm,
OperationType operation, PAddr map_addr) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
ASSERT(num_pages > 0);
ASSERT(Common::IsAligned(addr, PageSize));
@@ -1123,7 +1123,7 @@ ResultCode PageTable::CheckMemoryState(MemoryState* out_state, MemoryPermission*
MemoryPermission perm_mask, MemoryPermission perm,
MemoryAttribute attr_mask, MemoryAttribute attr,
MemoryAttribute ignore_attr) {
std::lock_guard lock{page_table_lock};
KScopedLightLock lk{general_lock};
// Get information about the first block
const VAddr last_addr{addr + size - 1};

View File

@@ -111,7 +111,7 @@ private:
perm, attr_mask, attr, ignore_attr);
}
std::recursive_mutex page_table_lock;
KLightLock general_lock;
std::unique_ptr<MemoryBlockManager> block_manager;
public: