mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-06 00:40:11 +00:00
Fix sys_vm_t destructor
It's not a destructor's job to free vm like this.
This commit is contained in:
parent
5af8a9fbbc
commit
00895862e1
@ -17,12 +17,6 @@ sys_vm_t::~sys_vm_t()
|
||||
{
|
||||
// Free ID
|
||||
g_ids[addr >> 28].release(id_manager::id_traits<sys_vm_t>::invalid);
|
||||
|
||||
// Free block
|
||||
verify(HERE), vm::unmap(addr);
|
||||
|
||||
// Return memory
|
||||
ct->used -= psize;
|
||||
}
|
||||
|
||||
LOG_CHANNEL(sys_vm);
|
||||
@ -92,7 +86,16 @@ error_code sys_vm_unmap(ppu_thread& ppu, u32 addr)
|
||||
}
|
||||
|
||||
// Free block and info
|
||||
if (!idm::remove<sys_vm_t>(sys_vm_t::find_id(addr)))
|
||||
const auto vmo = idm::withdraw<sys_vm_t>(sys_vm_t::find_id(addr), [&](sys_vm_t& vmo)
|
||||
{
|
||||
// Free block
|
||||
verify(HERE), vm::unmap(addr);
|
||||
|
||||
// Return memory
|
||||
vmo.ct->used -= vmo.psize;
|
||||
});
|
||||
|
||||
if (!vmo)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
@ -111,21 +114,32 @@ error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const auto block = idm::get<sys_vm_t>(sys_vm_t::find_id(addr));
|
||||
const auto block = idm::check<sys_vm_t>(sys_vm_t::find_id(addr), [&](sys_vm_t& vmo) -> CellError
|
||||
{
|
||||
if (vmo.addr != addr)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!block || block->addr != addr)
|
||||
if (!vmo.ct->take(size))
|
||||
{
|
||||
return CELL_ENOMEM;
|
||||
}
|
||||
|
||||
vmo.psize += size;
|
||||
return {};
|
||||
});
|
||||
|
||||
if (!block)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::lock_guard lock(block->mutex);
|
||||
|
||||
if (!block->ct->take(size))
|
||||
if (block.ret)
|
||||
{
|
||||
return CELL_ENOMEM;
|
||||
return block.ret;
|
||||
}
|
||||
|
||||
block->psize += size;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
@ -140,22 +154,43 @@ error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u32 size)
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
const auto block = idm::get<sys_vm_t>(sys_vm_t::find_id(addr));
|
||||
const auto block = idm::check<sys_vm_t>(sys_vm_t::find_id(addr), [&](sys_vm_t& vmo) -> CellError
|
||||
{
|
||||
if (vmo.addr != addr)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
if (!block || block->addr != addr)
|
||||
auto [_, ok] = vmo.psize.fetch_op([&](u32& value)
|
||||
{
|
||||
if (value < 0x100000ull + size)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
value -= size;
|
||||
return true;
|
||||
});
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
}
|
||||
|
||||
vmo.ct->used -= size;
|
||||
return {};
|
||||
});
|
||||
|
||||
if (!block)
|
||||
{
|
||||
return CELL_EINVAL;
|
||||
}
|
||||
|
||||
std::lock_guard lock(block->mutex);
|
||||
|
||||
if (u64{block->psize} < u64{0x100000} + size)
|
||||
if (block.ret)
|
||||
{
|
||||
return CELL_EBUSY;
|
||||
return block.ret;
|
||||
}
|
||||
|
||||
block->psize -= size;
|
||||
block->ct->used -= size;
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
@ -38,8 +38,7 @@ struct sys_vm_t
|
||||
lv2_memory_container* const ct;
|
||||
const u32 addr;
|
||||
const u32 size;
|
||||
u32 psize;
|
||||
shared_mutex mutex;
|
||||
atomic_t<u32> psize;
|
||||
|
||||
sys_vm_t(u32 addr, u32 vsize, lv2_memory_container* ct, u32 psize);
|
||||
~sys_vm_t();
|
||||
|
Loading…
x
Reference in New Issue
Block a user