vm: Fix writer lock leak

This commit is contained in:
Eladash 2024-03-27 10:36:00 +02:00 committed by Elad Ashkenazi
parent 4594c912a6
commit 8588b2b11a
3 changed files with 22 additions and 23 deletions

View file

@ -3376,25 +3376,29 @@ static bool ppu_store_reservation(ppu_thread& ppu, u32 addr, u64 reg_value)
//auto& cline_data = vm::_ref<spu_rdata_t>(addr); //auto& cline_data = vm::_ref<spu_rdata_t>(addr);
data += 0; data += 0;
rsx::reservation_lock rsx_lock(addr, 128); auto range_lock = vm::alloc_range_lock();
auto& super_data = *vm::get_super_ptr<spu_rdata_t>(addr);
const bool success = [&]()
{ {
// Full lock (heavyweight) rsx::reservation_lock rsx_lock(addr, 128);
// TODO: vm::check_addr
vm::writer_lock lock(addr);
if (cmp_rdata(ppu.rdata, super_data)) auto& super_data = *vm::get_super_ptr<spu_rdata_t>(addr);
const bool success = [&]()
{ {
data.release(new_data); // Full lock (heavyweight)
res += 64; // TODO: vm::check_addr
return true; vm::writer_lock lock(addr, range_lock);
}
res -= 64; if (cmp_rdata(ppu.rdata, super_data))
return false; {
}(); data.release(new_data);
res += 64;
return true;
}
res -= 64;
return false;
}();
}
vm::free_range_lock(range_lock);
return success; return success;
} }

View file

@ -448,11 +448,6 @@ namespace vm
{ {
if (range_lock) if (range_lock)
{ {
if (!*range_lock)
{
return;
}
g_range_lock_bits[1] &= ~(1ull << (range_lock - g_range_lock_set)); g_range_lock_bits[1] &= ~(1ull << (range_lock - g_range_lock_set));
range_lock->release(0); range_lock->release(0);
return; return;

View file

@ -473,13 +473,13 @@ namespace vm
} }
} }
bool to_prepare_memory = addr >= 0x10000; bool to_prepare_memory = true;
for (u64 i = 0;; i++) for (u64 i = 0;; i++)
{ {
auto& bits = get_range_lock_bits(true); auto& bits = get_range_lock_bits(true);
if (!range_lock || addr < 0x10000) if (!range_lock)
{ {
if (!bits && bits.compare_and_swap_test(0, u64{umax})) if (!bits && bits.compare_and_swap_test(0, u64{umax}))
{ {
@ -521,7 +521,7 @@ namespace vm
} }
} }
if (addr >= 0x10000) if (range_lock)
{ {
perf_meter<"SUSPEND"_u64> perf0; perf_meter<"SUSPEND"_u64> perf0;