SPU: Make recompilers lock-free.

This commit is contained in:
Nekotekina 2019-10-26 00:52:56 +03:00
parent 9ac6ef6494
commit 8c28c4e8ec
4 changed files with 248 additions and 260 deletions

View file

@ -45,24 +45,23 @@ void spu_recompiler::init()
}
}
spu_function_t spu_recompiler::compile(const std::vector<u32>& func, void* fn_location)
spu_function_t spu_recompiler::compile(std::vector<u32>&& _func)
{
if (!fn_location)
{
fn_location = m_spurt->find(func);
}
const auto add_loc = m_spurt->add_empty(std::move(_func));
if (fn_location == spu_runtime::g_dispatcher)
{
return &dispatch;
}
if (!fn_location)
if (!add_loc)
{
return nullptr;
}
if (auto cache = g_fxo->get<spu_cache>(); cache && g_cfg.core.spu_cache)
if (add_loc->compiled)
{
return add_loc->compiled;
}
const std::vector<u32>& func = add_loc->data;
if (auto cache = g_fxo->get<spu_cache>(); cache && g_cfg.core.spu_cache && !add_loc->cached.exchange(1))
{
cache->add(func);
}
@ -94,10 +93,10 @@ spu_function_t spu_recompiler::compile(const std::vector<u32>& func, void* fn_lo
X86Assembler compiler(&code);
this->c = &compiler;
if (g_cfg.core.spu_debug)
if (g_cfg.core.spu_debug && !add_loc->logged.exchange(1))
{
// Dump analyser data
this->dump(log);
this->dump(func, log);
fs::file(m_spurt->get_cache_path() + "spu.log", fs::write + fs::append).write(log);
// Set logger
@ -892,12 +891,21 @@ spu_function_t spu_recompiler::compile(const std::vector<u32>& func, void* fn_lo
LOG_FATAL(SPU, "Failed to build a function");
}
if (!m_spurt->add(fn_location, fn))
// Install compiled function pointer
const bool added = !add_loc->compiled && add_loc->compiled.compare_and_swap_test(nullptr, fn);
// Rebuild trampoline if necessary
if (!m_spurt->rebuild_ubertrampoline(func[1]))
{
return nullptr;
}
if (g_cfg.core.spu_debug)
if (added)
{
add_loc->compiled.notify_all();
}
if (g_cfg.core.spu_debug && added)
{
// Add ASMJIT logs
fmt::append(log, "Address: %p\n\n", fn);