Correct when we process the stepping queue. Also, the jitLock mutex is no longer needed.

This commit is contained in:
Henrik Rydgård committed 2026-08-16 13:33:26 +02:00
1 parent 1848262bea
commit a49f4523cb
13 files changed
+24 -48

No files matched your search

+5 -5
View File
@@ -301,11 +301,6 @@ bool Core_GetPowerSaving() {
void Core_RunLoopUntil(u64 globalticks) {
while (true) {
// Drain any functions queued up by Core_RunOnCPUThread() from other threads. Doing this at the
// top of this loop means it's reached at least once per call (i.e. about once per host frame)
// even while the CPU is fully running, and continuously (in a tight spin) while it's stepping/paused.
Core_ProcessCPUQueue();
switch (coreState) {
case CORE_POWERDOWN:
case CORE_RUNTIME_ERROR:
@@ -467,6 +462,11 @@ static void Core_PerformCPUStep(MIPSDebugInterface *cpu, CPUStepType stepType, i
static bool Core_ProcessStepping(MIPSDebugInterface *cpu) {
Core_StateProcessed();
// Drain any functions queued up by Core_RunOnCPUThread() from other threads. Doing this at the
// top of this loop means it's reached at least once per call (i.e. about once per host frame)
// even while the CPU is fully running, and continuously (in a tight spin) while it's stepping/paused.
Core_ProcessCPUQueue();
// Check if there's any pending save state actions.
SaveState::Process();
+2 -3
View File
@@ -73,9 +73,9 @@ static AutoDisabledReplacements LockMemory(bool keepReplacements) {
result.saved = true;
// Okay, save so we can restore later.
result.replacements = SaveAndClearReplacements();
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit)
if (MIPSComp::jit) {
result.emuhacks = MIPSComp::jit->SaveAndClearEmuHackOps();
}
}
return result;
}
@@ -91,7 +91,6 @@ AutoDisabledReplacements::AutoDisabledReplacements(AutoDisabledReplacements &&ot
AutoDisabledReplacements::~AutoDisabledReplacements() {
if (saved) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit)
MIPSComp::jit->RestoreSavedEmuHackOps(emuhacks);
RestoreSavedReplacements(replacements);
+1 -4
View File
@@ -57,7 +57,6 @@
namespace MIPSComp {
JitInterface *jit;
std::recursive_mutex jitLock;
void JitAt() {
// TODO: We could probably check for a bad pc here, and fire an exception. Could spare us from some crashes.
@@ -185,7 +184,6 @@ std::string AddAddress(const std::string &buf, uint64_t addr) {
#if PPSSPP_ARCH(ARM64) || defined(DISASM_ALL)
static bool Arm64SymbolCallback(char *buffer, int bufsize, uint8_t *address) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
std::string name;
if (MIPSComp::jit->DescribeCodePtr(address, name)) {
@@ -275,11 +273,10 @@ const char *ppsspp_resolver(struct ud*,
// But these do.
// UGLY HACK because the API is terrible
// UGLY HACK because the disassembler API is terrible
static char buf[128];
std::string str;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr((u8 *)(uintptr_t)addr, str)) {
*offset = 0;
truncate_cpy(buf, sizeof(buf), str);
-2
View File
@@ -17,7 +17,6 @@
#pragma once
#include <mutex>
#include <string>
#include <vector>
@@ -170,7 +169,6 @@ namespace MIPSComp {
u32 ResolveNotTakenTarget(const BranchInfo &branchInfo);
extern JitInterface *jit;
extern std::recursive_mutex jitLock;
void DoDummyJitState(PointerWrap &p);
+3 -12
View File
@@ -161,7 +161,6 @@ MIPSState::~MIPSState() {
}
void MIPSState::Shutdown() {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::JitInterface *oldjit = MIPSComp::jit;
if (oldjit) {
MIPSComp::jit = nullptr;
@@ -209,7 +208,6 @@ void MIPSState::Init() {
memset(vcmpResult, 0, sizeof(vcmpResult));
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (PSP_CoreParameter().cpuCore == CPUCore::JIT || PSP_CoreParameter().cpuCore == CPUCore::JIT_IR) {
MIPSComp::jit = MIPSComp::CreateNativeJit(this, PSP_CoreParameter().cpuCore == CPUCore::JIT_IR);
} else if (PSP_CoreParameter().cpuCore == CPUCore::IR_INTERPRETER) {
@@ -231,12 +229,9 @@ void MIPSState::UpdateCore(CPUCore desired) {
IncrementDebugCounter(DebugCounter::CPUCORE_SWITCHES);
// Get rid of the old JIT first, before switching.
{
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
delete MIPSComp::jit;
MIPSComp::jit = nullptr;
}
if (MIPSComp::jit) {
delete MIPSComp::jit;
MIPSComp::jit = nullptr;
}
PSP_CoreParameter().cpuCore = desired;
@@ -264,7 +259,6 @@ void MIPSState::UpdateCore(CPUCore desired) {
break;
}
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
MIPSComp::jit = newjit;
}
@@ -356,7 +350,6 @@ int MIPSState::RunLoopUntil(u64 globalTicks) {
static std::vector<std::pair<u32, int>> pendingClears;
void MIPSState::ProcessPendingClears() {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
for (auto &p : pendingClears) {
if (p.first == 0 && p.second == 0)
MIPSComp::jit->ClearCache();
@@ -370,14 +363,12 @@ void MIPSState::ProcessPendingClears() {
void MIPSState::InvalidateICache(u32 address, int length) {
// Only really applies to jit.
// Note that the backend is responsible for ensuring native code can still be returned to.
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit && length != 0) {
MIPSComp::jit->InvalidateCacheAt(address, length);
}
}
void MIPSState::ClearJitCache() {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
if (coreState == CORE_RUNNING_CPU || insideJit) {
pendingClears.emplace_back(0, 0);
-3
View File
@@ -19,7 +19,6 @@
#include <cstdint>
#include <unordered_set>
#include <mutex>
#include <sstream>
#include "Common/StringUtils.h"
@@ -121,8 +120,6 @@ bool HandleFault(uintptr_t hostAddress, void *ctx) {
SContext *context = (SContext *)ctx;
const uint8_t *codePtr = (uint8_t *)(context->CTX_PC);
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
// We set this later if we think it can be resumed from.
g_lastCrashAddress = nullptr;
-1
View File
@@ -165,7 +165,6 @@ int g_screenshotFailures;
// These must be saved before copying out memory and restored after.
auto savedReplacements = SaveAndClearReplacements();
if (MIPSComp::jit && p.mode == p.MODE_WRITE) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
std::vector<u32> savedBlocks;
savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps();
-2
View File
@@ -359,7 +359,6 @@ void CwCheatScreen::onFinish(DialogResult result) {
if (result != DR_BACK) // This only works for BACK here.
return;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
MIPSComp::jit->ClearCache();
}
@@ -385,7 +384,6 @@ void CwCheatScreen::OnAddCheat(UI::EventParams &params) {
void CwCheatScreen::OnEditCheatFile(UI::EventParams &params) {
g_Config.bReloadCheats = true;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
MIPSComp::jit->ClearCache();
}
-2
View File
@@ -337,7 +337,6 @@ void JitCompareScreen::OnBlockClick(UI::EventParams &e) {
}
void JitCompareScreen::OnAddressChange(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) {
return;
}
@@ -364,7 +363,6 @@ void JitCompareScreen::OnSelectBlock(UI::EventParams &e) {
}
void JitCompareScreen::OnBlockAddress(UI::EventParams &e) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (!MIPSComp::jit) {
return;
}
-1
View File
@@ -67,7 +67,6 @@ void HandleCommonMessages(UIMessage message, const char *value, ScreenManager *m
if (message == UIMessage::REQUEST_CLEAR_JIT && PSP_IsInited()) {
// TODO: This seems to clearly be the wrong place to handle this.
if (MIPSComp::jit) {
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit)
MIPSComp::jit->ClearCache();
}
+4 -6
View File
@@ -1280,12 +1280,10 @@ void NativeFrame(GraphicsContext *graphicsContext) {
g_screenManager->getUIContext()->SetTintSaturation(g_Config.fUITint, g_Config.fUISaturation);
// Drain any work queued by Core_RunOnCPUThread() from other threads. Core_RunLoopUntil()
// (called from within render() below, but only while a game is actually loaded/running)
// also does this, but that path isn't reached at all outside a game - e.g. from the main
// menu - so queued work would otherwise hang forever waiting for it. See Core_ProcessCPUQueue()
// in Core.h.
Core_ProcessCPUQueue();
if (GetUIState() != UISTATE_INGAME) {
// In case there are any cross thread requests outside the game.
Core_ProcessCPUQueue();
}
// All actual rendering (and also emulation) happens in this render() call.
renderFlags = g_screenManager->Render([]() {
-1
View File
@@ -102,7 +102,6 @@ INT_PTR CALLBACK DumpMemoryWindow::dlgFunc(HWND hwnd, UINT iMsg, WPARAM wParam,
fwrite(Memory::GetPointerOrException(bp->start), 1, bp->size, output);
} else {
auto savedReplacements = SaveAndClearReplacements();
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit) {
auto savedBlocks = MIPSComp::jit->SaveAndClearEmuHackOps();
fwrite(Memory::GetPointerOrException(bp->start), 1, bp->size, output);
+9 -6
View File
@@ -1017,22 +1017,25 @@ namespace MainWindow {
return TRUE;
case VERYSLEEPY_WPARAM_GETADDRINFO:
{
{
Core_RunOnCPUThread([lParam]() {
// This is called from VerySleepy, which is on a different thread than the CPU thread.
// We need to run this on the CPU thread to avoid race conditions.
VerySleepy_AddrInfo *info = (VerySleepy_AddrInfo *)lParam;
const u8 *ptr = (const u8 *)info->addr;
std::string name;
std::lock_guard<std::recursive_mutex> guard(MIPSComp::jitLock);
if (MIPSComp::jit && MIPSComp::jit->DescribeCodePtr(ptr, name)) {
swprintf_s(info->name, L"Jit::%S", name.c_str());
return TRUE;
return;
}
if (gpu && gpu->DescribeCodePtr(ptr, name)) {
swprintf_s(info->name, L"GPU::%S", name.c_str());
return TRUE;
return;
}
}
return FALSE;
});
return TRUE;
}
default:
return FALSE;