For Qt GUI, changed instruction tracing to be enabled/disabled by registering callback functions. This increases efficiency when tracing is disabled.

This commit is contained in:
harry 2024-03-18 06:02:30 -04:00
parent 5eeeb2219f
commit 55654f7191
4 changed files with 157 additions and 1 deletions

View File

@ -19,6 +19,14 @@ unsigned int debuggerPageSize = 14;
int vblankScanLines = 0; //Used to calculate scanlines 240-261 (vblank)
int vblankPixel = 0; //Used to calculate the pixels in vblank
struct TraceInstructionCallback
{
void (*func)(uint8 *opcode, int size) = nullptr;
TraceInstructionCallback* next = nullptr;
};
static TraceInstructionCallback* traceInstructionCB = nullptr;
int offsetStringToInt(unsigned int type, const char* offsetBuffer, bool *conversionOk)
{
int offset = -1;
@ -989,5 +997,82 @@ void DebugCycle()
if(debug_loggingCD)
LogCDData(opcode, A, size);
#ifdef __WIN_DRIVER__
FCEUD_TraceInstruction(opcode, size);
#else
// Use callback pointer that can be null checked, this saves on the overhead
// of calling a function for every instruction when we aren't tracing.
if (traceInstructionCB != nullptr)
{
auto* cb = traceInstructionCB;
while (cb != nullptr)
{
cb->func(opcode, size);
cb = cb->next;
}
}
#endif
}
void* FCEUI_TraceInstructionRegister( void (*func)(uint8*,int) )
{
TraceInstructionCallback* cb = nullptr;
if (traceInstructionCB == nullptr)
{
cb = traceInstructionCB = new TraceInstructionCallback();
cb->func = func;
}
else
{
cb = traceInstructionCB;
while (cb != nullptr)
{
if (cb->func == func)
{
// This function has already been registered, don't double add.
return nullptr;
}
if (cb->next == nullptr)
{
auto* newCB = new TraceInstructionCallback();
newCB->func = func;
cb->next = newCB;
return newCB;
}
cb = cb->next;
}
}
return cb;
}
bool FCEUI_TraceInstructionUnregisterHandle( void* handle )
{
TraceInstructionCallback* cb, *cb_prev, *cb_handle;
cb_handle = static_cast<TraceInstructionCallback*>(handle);
cb_prev = nullptr;
cb = traceInstructionCB;
while (cb != nullptr)
{
if (cb == cb_handle)
{ // Match we are going to remove from list and delete
if (cb_prev != nullptr)
{
cb_prev = cb->next;
}
else
{
traceInstructionCB = cb->next;
}
delete cb;
return true;
}
cb_prev = cb;
cb = cb->next;
}
return false;
}

View File

@ -175,4 +175,7 @@ DebuggerState &FCEUI_Debugger();
int offsetStringToInt(unsigned int type, const char* offsetBuffer, bool *conversionOk = nullptr);
unsigned int NewBreak(const char* name, int start, int end, unsigned int type, const char* condition, unsigned int num, bool enable);
void* FCEUI_TraceInstructionRegister( void (*func)(uint8*,int) );
bool FCEUI_TraceInstructionUnregisterHandle( void* handle );
#endif

View File

@ -41,6 +41,7 @@
//--- NetPlay State Monitoring Metrics
//-----------------------------------------------------------------------------
static uint32_t opsCrc32 = 0;
static void *traceRegistrationHandle = nullptr;
struct NetPlayFrameData
{
@ -202,6 +203,12 @@ int NetPlayServer::Create(QObject *parent)
printf("Error Creating Netplay Server!!!\n");
}
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( NetPlayTraceInstruction );
}
FCEU_WRAPPER_UNLOCK();
return 0;
}
@ -213,6 +220,16 @@ int NetPlayServer::Destroy()
delete server;
server = nullptr;
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
return 0;
}
@ -890,6 +907,12 @@ int NetPlayClient::Create(QObject *parent)
printf("Error Creating Netplay Client!!!\n");
}
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( NetPlayTraceInstruction );
}
FCEU_WRAPPER_UNLOCK();
return 0;
}
@ -901,6 +924,16 @@ int NetPlayClient::Destroy()
delete client;
client = nullptr;
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
return 0;
}
//-----------------------------------------------------------------------------
@ -2181,6 +2214,6 @@ void NetPlayOnFrameBegin()
netPlayFrameData.push( data );
//printf("Frame: %u Ops:%08X \n", data.frameNum, data.opsCrc32 );
//printf("Frame: %u Ops:%08X Ram:%08X\n", data.frameNum, data.opsCrc32, data.ramCrc32 );
}
//----------------------------------------------------------------------------

View File

@ -131,6 +131,7 @@ static HANDLE logFile = INVALID_HANDLE_VALUE;
static int logFile = -1;
#endif
static std::string logFilePath;
static void* traceRegistrationHandle = nullptr;
//----------------------------------------------------
static void initLogOption( const char *name, int bitmask )
{
@ -524,6 +525,16 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void)
diskThread->quit();
diskThread->wait(1000);
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
traceView->update();
}
else
@ -540,7 +551,14 @@ void TraceLoggerDialog_t::toggleLoggingOnOff(void)
pushMsgToLogBuffer("Log Start");
startStopButton->setText(tr("Stop Logging"));
startStopButton->setIcon( style()->standardIcon( QStyle::SP_MediaStop ) );
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( FCEUD_TraceInstruction );
}
logging = 1;
FCEU_WRAPPER_UNLOCK();
}
}
//----------------------------------------------------
@ -1153,7 +1171,13 @@ int FCEUD_TraceLoggerStart(void)
{
initTraceLogBuffer(1000000);
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle == nullptr)
{
traceRegistrationHandle = FCEUI_TraceInstructionRegister( FCEUD_TraceInstruction );
}
logging = 1;
FCEU_WRAPPER_UNLOCK();
}
return logging;
}
@ -1174,6 +1198,17 @@ int FCEUD_TraceLoggerStop(void)
msleep(1);
pushMsgToLogBuffer("Logging Finished");
}
FCEU_WRAPPER_LOCK();
if (traceRegistrationHandle != nullptr)
{
if ( !FCEUI_TraceInstructionUnregisterHandle( traceRegistrationHandle ) )
{
printf("Unregister Trace Callback Error\n");
}
traceRegistrationHandle = nullptr;
}
FCEU_WRAPPER_UNLOCK();
return logging;
}
//----------------------------------------------------