mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-10 00:41:26 +12:00
Implement vm::find_map; improve memory allocation
Add vm::user64k and vm::user1m constants Remove vm::user_space, unreserve it
This commit is contained in:
parent
9578e1e923
commit
aa4040bb7b
10 changed files with 139 additions and 67 deletions
|
@ -711,6 +711,41 @@ namespace vm
|
|||
return imp_used(lock);
|
||||
}
|
||||
|
||||
static bool _test_map(u32 addr, u32 size)
|
||||
{
|
||||
for (auto& block : g_locations)
|
||||
{
|
||||
if (block && block->addr >= addr && block->addr <= addr + size - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (block && addr >= block->addr && addr <= block->addr + block->size - 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static std::shared_ptr<block_t> _find_map(u32 size, u32 align, u64 flags)
|
||||
{
|
||||
for (u32 addr = ::align<u32>(0x20000000, align); addr < 0xC0000000; addr += align)
|
||||
{
|
||||
if (_test_map(addr, size))
|
||||
{
|
||||
auto block = std::make_shared<block_t>(addr, size, flags);
|
||||
|
||||
g_locations.emplace_back(block);
|
||||
|
||||
return block;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::shared_ptr<block_t> map(u32 addr, u32 size, u64 flags)
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
|
@ -720,17 +755,9 @@ namespace vm
|
|||
fmt::throw_exception("Invalid arguments (addr=0x%x, size=0x%x)" HERE, addr, size);
|
||||
}
|
||||
|
||||
for (auto& block : g_locations)
|
||||
if (!_test_map(addr, size))
|
||||
{
|
||||
if (block->addr >= addr && block->addr <= addr + size - 1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (addr >= block->addr && addr <= block->addr + block->size - 1)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for (u32 i = addr / 4096; i < addr / 4096 + size / 4096; i++)
|
||||
|
@ -748,6 +775,28 @@ namespace vm
|
|||
return block;
|
||||
}
|
||||
|
||||
std::shared_ptr<block_t> find_map(u32 orig_size, u32 align, u64 flags)
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
|
||||
// Align to minimal page size
|
||||
const u32 size = ::align(orig_size, 0x10000);
|
||||
|
||||
// Check alignment
|
||||
if (align < 0x10000 || align != (0x80000000u >> ::cntlz32(align, true)))
|
||||
{
|
||||
fmt::throw_exception("Invalid alignment (size=0x%x, align=0x%x)" HERE, size, align);
|
||||
}
|
||||
|
||||
// Return if size is invalid
|
||||
if (!size || size > 0x40000000)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return _find_map(size, align, flags);
|
||||
}
|
||||
|
||||
std::shared_ptr<block_t> unmap(u32 addr, bool must_be_empty)
|
||||
{
|
||||
vm::writer_lock lock(0);
|
||||
|
@ -756,6 +805,16 @@ namespace vm
|
|||
{
|
||||
if (*it && (*it)->addr == addr)
|
||||
{
|
||||
if (must_be_empty && (*it)->flags & 0x3)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!must_be_empty && ((*it)->flags & 0x3) != 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (must_be_empty && (!it->unique() || (*it)->imp_used(lock)))
|
||||
{
|
||||
return *it;
|
||||
|
@ -779,7 +838,25 @@ namespace vm
|
|||
// return selected location
|
||||
if (location < g_locations.size())
|
||||
{
|
||||
return g_locations[location];
|
||||
auto& loc = g_locations[location];
|
||||
|
||||
if (!loc)
|
||||
{
|
||||
if (location == vm::user64k || location == vm::user1m)
|
||||
{
|
||||
g_mutex.lock_upgrade();
|
||||
|
||||
if (!loc)
|
||||
{
|
||||
// Deferred allocation
|
||||
loc = _find_map(0x10000000, 0x10000000, location == vm::user64k ? 0x201 : 0x401);
|
||||
}
|
||||
|
||||
g_mutex.lock_degrade();
|
||||
}
|
||||
}
|
||||
|
||||
return loc;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -788,7 +865,7 @@ namespace vm
|
|||
// search location by address
|
||||
for (auto& block : g_locations)
|
||||
{
|
||||
if (addr >= block->addr && addr <= block->addr + block->size - 1)
|
||||
if (block && addr >= block->addr && addr <= block->addr + block->size - 1)
|
||||
{
|
||||
return block;
|
||||
}
|
||||
|
@ -804,9 +881,10 @@ namespace vm
|
|||
g_locations =
|
||||
{
|
||||
std::make_shared<block_t>(0x00010000, 0x1FFF0000), // main
|
||||
std::make_shared<block_t>(0x20000000, 0x10000000), // user
|
||||
std::make_shared<block_t>(0xC0000000, 0x10000000), // video
|
||||
std::make_shared<block_t>(0xD0000000, 0x10000000), // stack
|
||||
nullptr, // user 64k pages
|
||||
nullptr, // user 1m pages
|
||||
std::make_shared<block_t>(0xE0000000, 0x20000000), // SPU reserved
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue