mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-06 15:01:28 +12:00
asmjit: Minimal locking when reading, also only lock when actually writing to the db
This commit is contained in:
parent
f69121116a
commit
78f09d7645
1 changed files with 53 additions and 15 deletions
|
@ -12,8 +12,23 @@ std::shared_ptr<spu_function_t> SPUDatabase::find(const be_t<u32>* data, u64 key
|
||||||
const auto& func = found.first->second;
|
const auto& func = found.first->second;
|
||||||
|
|
||||||
// Compare binary data explicitly (TODO: optimize)
|
// Compare binary data explicitly (TODO: optimize)
|
||||||
if (LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0)
|
//if (LIKELY(func->size <= max_size) && std::memcmp(func->data.data(), data, func->size) == 0)
|
||||||
{
|
{
|
||||||
|
const auto dwords = (u32*)(func->data.data());
|
||||||
|
const auto cast_data = (u32*)(data);
|
||||||
|
const auto limit = std::min(max_size, func->size) >> 2;
|
||||||
|
|
||||||
|
bool failed = false;
|
||||||
|
for (u32 dword = 0; dword < limit; dword++)
|
||||||
|
{
|
||||||
|
if (dwords[dword] != cast_data[dword])
|
||||||
|
{
|
||||||
|
failed = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!failed)
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,24 +58,28 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||||
|
|
||||||
// Key for multimap
|
// Key for multimap
|
||||||
const u64 key = entry | u64{ ls[entry / 4] } << 32;
|
const u64 key = entry | u64{ ls[entry / 4] } << 32;
|
||||||
|
const be_t<u32>* base = ls + entry / 4;
|
||||||
|
const u32 block_sz = max_limit - entry;
|
||||||
|
|
||||||
{
|
{
|
||||||
reader_lock lock(m_mutex);
|
//reader_lock lock(m_mutex);
|
||||||
|
|
||||||
// Try to find existing function in the database
|
// Try to find existing function in the database
|
||||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
if (auto func = find(base, key, block_sz))
|
||||||
{
|
{
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
writer_lock lock(m_mutex);
|
writer_lock lock(m_mutex);
|
||||||
|
|
||||||
// Double-check
|
// Double-check
|
||||||
if (auto func = find(ls + entry / 4, key, max_limit - entry))
|
if (auto func = find(base, key, block_sz))
|
||||||
{
|
{
|
||||||
return func;
|
return func;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Initialize block entries with the function entry point
|
// Initialize block entries with the function entry point
|
||||||
std::set<u32> blocks{ entry };
|
std::set<u32> blocks{ entry };
|
||||||
|
@ -81,12 +100,16 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||||
|
|
||||||
const auto type = s_spu_itype.decode(op.opcode);
|
const auto type = s_spu_itype.decode(op.opcode);
|
||||||
|
|
||||||
|
{
|
||||||
|
//reader_lock lock(m_mutex);
|
||||||
|
|
||||||
// Find existing function
|
// Find existing function
|
||||||
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
if (pos != entry && find(ls + pos / 4, pos | u64{ op.opcode } << 32, limit - pos))
|
||||||
{
|
{
|
||||||
limit = pos;
|
limit = pos;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Additional analysis at the beginning of the block
|
// Additional analysis at the beginning of the block
|
||||||
if (start != entry && start == pos)
|
if (start != entry && start == pos)
|
||||||
|
@ -311,8 +334,23 @@ std::shared_ptr<spu_function_t> SPUDatabase::analyse(const be_t<u32>* ls, u32 en
|
||||||
// Set whether the function can reset stack
|
// Set whether the function can reset stack
|
||||||
func->does_reset_stack = ila_sp_pos < limit;
|
func->does_reset_stack = ila_sp_pos < limit;
|
||||||
|
|
||||||
|
// Lock here just before we write to the db
|
||||||
|
// Its is unlikely that the second check will pass anyway so we delay this step since compiling functions is very fast
|
||||||
|
{
|
||||||
|
writer_lock lock(m_mutex);
|
||||||
|
|
||||||
|
if (0)//funcs_length != m_db.size())
|
||||||
|
{
|
||||||
|
// Double-check if something new has been written before we got here
|
||||||
|
if (auto func = find(base, key, block_sz))
|
||||||
|
{
|
||||||
|
return func;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Add function to the database
|
// Add function to the database
|
||||||
m_db.emplace(key, func);
|
m_db.emplace(key, func);
|
||||||
|
}
|
||||||
|
|
||||||
LOG_SUCCESS(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
|
LOG_SUCCESS(SPU, "Function detected [0x%05x-0x%05x] (size=0x%x)", func->addr, func->addr + func->size, func->size);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue