diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 965dfdc31..f4a6b640e 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -399,10 +399,11 @@ struct AddressSpace::Impl { auto it = std::prev(regions.upper_bound(virtual_addr)); ASSERT_MSG(!it->second.is_mapped, "Cannot coalesce mapped regions"); - // Check if there are free placeholders before this area. + // Check if there are adjacent free placeholders before this area. bool can_coalesce = false; auto it_prev = it != regions.begin() ? std::prev(it) : regions.end(); - while (it_prev != regions.end() && !it_prev->second.is_mapped) { + while (it_prev != regions.end() && !it_prev->second.is_mapped && + it_prev->first + it_prev->second.size == it->first) { // If there is an earlier region, move our iterator to that and increase size. it_prev->second.size = it_prev->second.size + it->second.size; regions.erase(it); @@ -415,9 +416,10 @@ struct AddressSpace::Impl { it_prev = it != regions.begin() ? std::prev(it) : regions.end(); } - // Check if there are free placeholders after this area. + // Check if there are adjacent free placeholders after this area. auto it_next = std::next(it); - while (it_next != regions.end() && !it_next->second.is_mapped) { + while (it_next != regions.end() && !it_next->second.is_mapped && + it->first + it->second.size == it_next->first) { // If there is a later region, increase our current region's size it->second.size = it->second.size + it_next->second.size; regions.erase(it_next); diff --git a/src/core/memory.cpp b/src/core/memory.cpp index 0726e8711..32518907a 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -117,7 +117,6 @@ void MemoryManager::SetPrtArea(u32 id, VAddr address, u64 size) { } void MemoryManager::CopySparseMemory(VAddr virtual_addr, u8* dest, u64 size) { - std::shared_lock lk{mutex}; ASSERT_MSG(IsValidMapping(virtual_addr), "Attempted to access invalid address {:#x}", virtual_addr); @@ -138,7 +137,6 @@ void MemoryManager::CopySparseMemory(VAddr virtual_addr, u8* dest, u64 size) { bool MemoryManager::TryWriteBacking(void* address, const void* data, u64 size) { const VAddr virtual_addr = std::bit_cast(address); - std::shared_lock lk{mutex}; ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", virtual_addr); @@ -701,7 +699,7 @@ s32 MemoryManager::MapFile(void** out_addr, VAddr virtual_addr, u64 size, Memory } s32 MemoryManager::PoolDecommit(VAddr virtual_addr, u64 size) { - mutex.lock(); + std::scoped_lock lk{mutex}; ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", virtual_addr); @@ -710,7 +708,6 @@ s32 MemoryManager::PoolDecommit(VAddr virtual_addr, u64 size) { while (it != vma_map.end() && it->second.base + it->second.size <= virtual_addr + size) { if (it->second.type != VMAType::PoolReserved && it->second.type != VMAType::Pooled) { LOG_ERROR(Kernel_Vmm, "Attempting to decommit non-pooled memory!"); - mutex.unlock(); return ORBIS_KERNEL_ERROR_EINVAL; } it++; @@ -728,9 +725,7 @@ s32 MemoryManager::PoolDecommit(VAddr virtual_addr, u64 size) { if (vma_base.type == VMAType::Pooled) { // We always map PoolCommitted memory to GPU, so unmap when decomitting. if (IsValidGpuMapping(current_addr, size_in_vma)) { - mutex.unlock(); rasterizer->UnmapMemory(current_addr, size_in_vma); - mutex.lock(); } // Track how much pooled memory is decommitted @@ -781,7 +776,6 @@ s32 MemoryManager::PoolDecommit(VAddr virtual_addr, u64 size) { // Tracy memory tracking breaks from merging memory areas. Disabled for now. // TRACK_FREE(virtual_addr, "VMEM"); - mutex.unlock(); return ORBIS_OK; } @@ -789,13 +783,12 @@ s32 MemoryManager::UnmapMemory(VAddr virtual_addr, u64 size) { if (size == 0) { return ORBIS_OK; } - mutex.lock(); + std::scoped_lock lk{mutex}; virtual_addr = Common::AlignDown(virtual_addr, 16_KB); size = Common::AlignUp(size, 16_KB); ASSERT_MSG(IsValidMapping(virtual_addr, size), "Attempted to access invalid address {:#x}", virtual_addr); u64 bytes_unmapped = UnmapMemoryImpl(virtual_addr, size); - mutex.unlock(); return bytes_unmapped; } @@ -873,9 +866,7 @@ u64 MemoryManager::UnmapBytesFromEntry(VAddr virtual_addr, VirtualMemoryArea vma // If this mapping has GPU access, unmap from GPU. if (IsValidGpuMapping(virtual_addr, size)) { - mutex.unlock(); rasterizer->UnmapMemory(virtual_addr, size); - mutex.lock(); } } return size_in_vma;