1
0
mirror of https://github.com/RPCS3/rpcs3.git synced 2024-11-22 02:32:36 +01:00

SPU: Make JIT allocator lock-free on all platforms

This commit is contained in:
Nekotekina 2019-10-25 14:33:23 +03:00
parent 0c06456950
commit 2e85b5ebaa

View File

@ -8,10 +8,8 @@
#include "VirtualMemory.h" #include "VirtualMemory.h"
#include <immintrin.h> #include <immintrin.h>
// Memory manager mutex
shared_mutex s_mutex2;
#ifdef __linux__ #ifdef __linux__
#include <sys/mman.h>
#define CAN_OVERCOMMIT #define CAN_OVERCOMMIT
#endif #endif
@ -50,30 +48,32 @@ static u8* add_jit_memory(std::size_t size, uint align)
return pointer; return pointer;
} }
#ifndef CAN_OVERCOMMIT
std::lock_guard lock(s_mutex2);
#endif
u64 olda, newa; u64 olda, newa;
// Simple allocation by incrementing pointer to the next free data // Simple allocation by incrementing pointer to the next free data
const u64 pos = Ctr.atomic_op([&](u64& ctr) -> u64 const u64 pos = Ctr.atomic_op([&](u64& ctr) -> u64
{ {
const u64 _pos = ::align(ctr, align); const u64 _pos = ::align(ctr & 0xffff'ffff, align);
const u64 _new = ::align(_pos + size, align); const u64 _new = ::align(_pos + size, align);
if (UNLIKELY(_new > 0x40000000)) if (UNLIKELY(_new > 0x40000000))
{ {
// Sorry, we failed, and further attempts should fail too. // Sorry, we failed, and further attempts should fail too.
ctr = 0x40000000; ctr |= 0x40000000;
return -1; return -1;
} }
// Check the necessity to commit more memory // Last allocation is stored in highest bits
olda = ::align(ctr, 0x10000); olda = ctr >> 32;
newa = ::align(_new, 0x10000); newa = olda;
ctr = _new; // Check the necessity to commit more memory
if (UNLIKELY(_new > olda))
{
newa = ::align(_new, 0x100000);
}
ctr += _new - (ctr & 0xffff'ffff);
return _pos; return _pos;
}); });
@ -86,11 +86,19 @@ static u8* add_jit_memory(std::size_t size, uint align)
if (UNLIKELY(olda != newa)) if (UNLIKELY(olda != newa))
{ {
#ifdef CAN_OVERCOMMIT #ifdef CAN_OVERCOMMIT
// TODO: possibly madvise madvise(pointer + olda, newa - olda, MADV_WILLNEED);
#else #else
// Commit more memory // Commit more memory
utils::memory_commit(pointer + olda, newa - olda, Prot); utils::memory_commit(pointer + olda, newa - olda, Prot);
#endif #endif
// Acknowledge committed memory
Ctr.atomic_op([&](u64& ctr)
{
if ((ctr >> 32) < newa)
{
ctr += (newa - (ctr >> 32)) << 32;
}
});
} }
return pointer + pos; return pointer + pos;
@ -159,10 +167,10 @@ void jit_runtime::initialize()
} }
// Create code/data snapshot // Create code/data snapshot
s_code_init.resize(s_code_pos); s_code_init.resize(s_code_pos & 0xffff'ffff);
std::memcpy(s_code_init.data(), alloc(0, 0, true), s_code_pos); std::memcpy(s_code_init.data(), alloc(0, 0, true), s_code_init.size());
s_data_init.resize(s_data_pos); s_data_init.resize(s_data_pos & 0xffff'ffff);
std::memcpy(s_data_init.data(), alloc(0, 0, false), s_data_pos); std::memcpy(s_data_init.data(), alloc(0, 0, false), s_data_init.size());
} }
void jit_runtime::finalize() noexcept void jit_runtime::finalize() noexcept