mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-02-10 21:40:43 +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
|
// Free ID
|
||||||
g_ids[addr >> 28].release(id_manager::id_traits<sys_vm_t>::invalid);
|
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);
|
LOG_CHANNEL(sys_vm);
|
||||||
@ -92,7 +86,16 @@ error_code sys_vm_unmap(ppu_thread& ppu, u32 addr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Free block and info
|
// 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;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
@ -111,21 +114,32 @@ error_code sys_vm_append_memory(ppu_thread& ppu, u32 addr, u32 size)
|
|||||||
return CELL_EINVAL;
|
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;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(block->mutex);
|
if (block.ret)
|
||||||
|
|
||||||
if (!block->ct->take(size))
|
|
||||||
{
|
{
|
||||||
return CELL_ENOMEM;
|
return block.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->psize += size;
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -140,22 +154,43 @@ error_code sys_vm_return_memory(ppu_thread& ppu, u32 addr, u32 size)
|
|||||||
return CELL_EINVAL;
|
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;
|
return CELL_EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::lock_guard lock(block->mutex);
|
if (block.ret)
|
||||||
|
|
||||||
if (u64{block->psize} < u64{0x100000} + size)
|
|
||||||
{
|
{
|
||||||
return CELL_EBUSY;
|
return block.ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
block->psize -= size;
|
|
||||||
block->ct->used -= size;
|
|
||||||
return CELL_OK;
|
return CELL_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ struct sys_vm_t
|
|||||||
lv2_memory_container* const ct;
|
lv2_memory_container* const ct;
|
||||||
const u32 addr;
|
const u32 addr;
|
||||||
const u32 size;
|
const u32 size;
|
||||||
u32 psize;
|
atomic_t<u32> psize;
|
||||||
shared_mutex mutex;
|
|
||||||
|
|
||||||
sys_vm_t(u32 addr, u32 vsize, lv2_memory_container* ct, u32 psize);
|
sys_vm_t(u32 addr, u32 vsize, lv2_memory_container* ct, u32 psize);
|
||||||
~sys_vm_t();
|
~sys_vm_t();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user