SPU: Extend LS memory mirrors
This commit is contained in:
@@ -1733,21 +1733,48 @@ void spu_thread::cleanup()
|
|||||||
static_cast<named_thread<spu_thread>&>(*this) = thread_state::finished;
|
static_cast<named_thread<spu_thread>&>(*this) = thread_state::finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum : s64
|
||||||
|
{
|
||||||
|
SIGNED_LS_SIZE = SPU_LS_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
spu_thread::~spu_thread()
|
spu_thread::~spu_thread()
|
||||||
{
|
{
|
||||||
// Unmap LS and its mirrors
|
// Unmap LS and its mirrors
|
||||||
shm->unmap(ls + SPU_LS_SIZE);
|
for (s64 ls_offs = 0 - SIGNED_LS_SIZE * 2; ls_offs <= SIGNED_LS_SIZE * 2; ls_offs += SIGNED_LS_SIZE)
|
||||||
shm->unmap(ls);
|
{
|
||||||
shm->unmap(ls - SPU_LS_SIZE);
|
shm->unmap(ls + ls_offs);
|
||||||
utils::memory_release(ls - SPU_LS_SIZE * 2, SPU_LS_SIZE * 5);
|
}
|
||||||
|
|
||||||
|
utils::memory_release(ls - SIGNED_LS_SIZE * 3, SIGNED_LS_SIZE * 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* spu_thread::map_ls(utils::shm& shm, void* ptr)
|
u8* spu_thread::map_ls(utils::shm& shm, void* ptr)
|
||||||
{
|
{
|
||||||
|
const auto ls = ptr ? static_cast<u8*>(ptr) : static_cast<u8*>(ensure(utils::memory_reserve(SIGNED_LS_SIZE * 7, nullptr, true))) + SIGNED_LS_SIZE * 3;
|
||||||
|
|
||||||
vm::writer_lock mlock;
|
vm::writer_lock mlock;
|
||||||
|
|
||||||
const auto ls = ptr ? static_cast<u8*>(ptr) : static_cast<u8*>(ensure(utils::memory_reserve(SPU_LS_SIZE * 5, nullptr, true))) + SPU_LS_SIZE * 2;
|
for (s64 ls_offs = 0 - SIGNED_LS_SIZE * 2; ls_offs <= SIGNED_LS_SIZE * 2; ls_offs += SIGNED_LS_SIZE)
|
||||||
ensure(shm.map_critical(ls - SPU_LS_SIZE).first && shm.map_critical(ls).first && shm.map_critical(ls + SPU_LS_SIZE).first);
|
{
|
||||||
|
const auto [ptr_ret, str] = shm.map_critical(ls + ls_offs);
|
||||||
|
|
||||||
|
if (!ptr_ret)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("spu_thread::map_ls() failed: map_critical returned error (error=%s) [ls_offs=0x%x]", str, ls_offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ptr_ret != ls + ls_offs)
|
||||||
|
{
|
||||||
|
fmt::throw_exception("spu_thread::map_ls() failed: map_critical returned a different address: 0x%llx vs 0x%llx (error=%s) [ls_offs=0x%x]", ptr_ret, ls + ls_offs, str, ls_offs);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!str.empty())
|
||||||
|
{
|
||||||
|
fmt::throw_exception("spu_thread::map_ls() failed: map_critical returned unexpected error (error=%s) [ls_offs=0x%x]", str, ls_offs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ls;
|
return ls;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1792,7 +1819,7 @@ spu_thread::spu_thread(lv2_spu_group* group, u32 index, std::string_view name, u
|
|||||||
, index(index)
|
, index(index)
|
||||||
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
, thread_type(group ? spu_type::threaded : is_isolated ? spu_type::isolated : spu_type::raw)
|
||||||
, shm(std::make_shared<utils::shm>(SPU_LS_SIZE))
|
, shm(std::make_shared<utils::shm>(SPU_LS_SIZE))
|
||||||
, ls(static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 5, nullptr, true)) + SPU_LS_SIZE * 2)
|
, ls(static_cast<u8*>(utils::memory_reserve(SPU_LS_SIZE * 7, nullptr, true)) + SPU_LS_SIZE * 3)
|
||||||
, option(option)
|
, option(option)
|
||||||
, lv2_id(lv2_id)
|
, lv2_id(lv2_id)
|
||||||
, spu_tname(make_single<std::string>(name))
|
, spu_tname(make_single<std::string>(name))
|
||||||
|
|||||||
@@ -909,9 +909,14 @@ namespace utils
|
|||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
::MEMORY_BASIC_INFORMATION mem{};
|
::MEMORY_BASIC_INFORMATION mem{};
|
||||||
if (!::VirtualQuery(target, &mem, sizeof(mem)) || mem.State != MEM_RESERVE)
|
if (!::VirtualQuery(target, &mem, sizeof(mem)))
|
||||||
{
|
{
|
||||||
return {nullptr, fmt::format("VirtualQuery() Unexpceted memory info: state=0x%x, %s", mem.State, std::as_bytes(std::span(&mem, 1)))};
|
return {nullptr, fmt::format("VirtualQuery() Failed with %s", fmt::win_error{GetLastError(), nullptr})};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem.State != MEM_RESERVE)
|
||||||
|
{
|
||||||
|
return {nullptr, fmt::format("VirtualQuery() reported unexpected memory info: state=0x%x, %s", mem.State, std::as_bytes(std::span(&mem, 1)))};
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto base = static_cast<u8*>(mem.AllocationBase);
|
const auto base = static_cast<u8*>(mem.AllocationBase);
|
||||||
@@ -977,8 +982,14 @@ namespace utils
|
|||||||
return {nullptr, "VirtualAlloc() failed to reserve allocation end"};
|
return {nullptr, "VirtualAlloc() failed to reserve allocation end"};
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
const auto mapped_addr = this->map(target, prot, cow);
|
||||||
|
|
||||||
return {this->map(target, prot, cow), "Failed to map"};
|
if (!mapped_addr)
|
||||||
|
{
|
||||||
|
return {nullptr, "Failed to map"};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {mapped_addr, {}};
|
||||||
}
|
}
|
||||||
|
|
||||||
u8* shm::map_self(protection prot)
|
u8* shm::map_self(protection prot)
|
||||||
|
|||||||
Reference in New Issue
Block a user