[Project64] Use thread class for emulation thread

This commit is contained in:
zilmar 2016-04-18 05:52:09 +10:00
parent bddd3841cc
commit 9d5a33df6a
4 changed files with 39 additions and 60 deletions

View File

@ -3,7 +3,7 @@
class CThread
{
public:
typedef uint32_t(__stdcall * CTHREAD_START_ROUTINE)(void * lpThreadParameter);
typedef uint32_t(* CTHREAD_START_ROUTINE)(void * lpThreadParameter);
CThread(CTHREAD_START_ROUTINE lpStartAddress);
~CThread();

View File

@ -12,24 +12,19 @@
#include <Project64-core/N64System/N64Class.h>
#include <Project64-core/Notification.h>
#include <Common/Util.h>
#include <Windows.h>
#include <Objbase.h>
void CN64System::StartEmulationThead()
{
ThreadInfo * Info = new ThreadInfo;
HANDLE * hThread = new HANDLE;
*hThread = NULL;
//create the needed info into a structure to pass as one parameter
//for creating a thread
Info->ThreadHandle = hThread;
*hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)StartEmulationThread, Info, 0, (LPDWORD)&Info->ThreadID);
WriteTrace(TraceN64System, TraceDebug, "Start");
CThread * thread = new CThread((CThread::CTHREAD_START_ROUTINE)StartEmulationThread);
thread->Start(thread);
WriteTrace(TraceN64System, TraceDebug, "Done");
}
void CN64System::StartEmulationThread(ThreadInfo * Info)
void CN64System::StartEmulationThread(CThread * thread)
{
WriteTrace(TraceN64System, TraceDebug, "Start");
#ifdef _WIN32
if (g_Settings->LoadBool(Setting_CN64TimeCritical))
{
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
@ -37,61 +32,57 @@ void CN64System::StartEmulationThread(ThreadInfo * Info)
CoInitialize(NULL);
EmulationStarting(*Info->ThreadHandle, Info->ThreadID);
delete ((HANDLE *)Info->ThreadHandle);
delete Info;
EmulationStarting(thread);
CoUninitialize();
#else
EmulationStarting(thread);
#endif
WriteTrace(TraceN64System, TraceDebug, "Done");
}
void CN64System::CloseCpu()
{
if (m_CPU_Handle == NULL)
WriteTrace(TraceN64System, TraceDebug, "Start");
if (m_thread == NULL)
{
return;
}
WriteTrace(TraceN64System, TraceDebug, "Setting end emulation");
m_EndEmulation = true;
if (g_Settings->LoadBool(GameRunning_CPU_Paused))
{
WriteTrace(TraceN64System, TraceDebug, "Resume cpu");
m_hPauseEvent.Trigger();
}
if (GetCurrentThreadId() == m_CPU_ThreadID)
if (CThread::GetCurrentThreadId() == m_thread->ThreadID())
{
WriteTrace(TraceN64System, TraceDebug, "CloseCpu called on emulation thread");
ExternalEvent(SysEvent_CloseCPU);
return;
}
HANDLE hThread = m_CPU_Handle;
m_CPU_Handle = NULL;
CThread * hThread = m_thread;
m_thread = NULL;
for (int count = 0; count < 200; count++)
{
if (hThread == NULL || !hThread->isRunning())
{
WriteTrace(TraceN64System, TraceDebug, "Thread no longer running");
break;
}
WriteTrace(TraceN64System, TraceDebug, "%d - waiting", count);
pjutil::Sleep(100);
WriteTrace(TraceN64System, TraceDebug, "%d - Finished wait", count);
if (g_Notify->ProcessGuiMessages())
{
return;
}
DWORD ExitCode;
if (GetExitCodeThread(hThread, &ExitCode))
{
if (ExitCode != STILL_ACTIVE)
{
break;
}
}
}
if (hThread)
{
DWORD ExitCode;
GetExitCodeThread(hThread, &ExitCode);
if (ExitCode == STILL_ACTIVE)
{
TerminateThread(hThread, 0);
}
}
CloseHandle(hThread);
CpuStopped();
WriteTrace(TraceN64System, TraceDebug, "Deleting thread object");
delete hThread;
WriteTrace(TraceN64System, TraceDebug, "Done");
}

View File

@ -26,9 +26,6 @@
#pragma warning(disable:4355) // Disable 'this' : used in base member initializer list
#include <windows.h>
#include <commdlg.h>
CN64System::CN64System(CPlugins * Plugins, bool SavesReadOnly) :
CSystemEvents(this, Plugins),
m_EndEmulation(false),
@ -53,8 +50,7 @@ m_JumpToLocation(0),
m_TLBLoadAddress(0),
m_TLBStoreAddress(0),
m_SyncCount(0),
m_CPU_Handle(NULL),
m_CPU_ThreadID(0),
m_thread(NULL),
m_hPauseEvent(true),
m_CheatsSlectionChanged(false)
{
@ -373,16 +369,15 @@ void CN64System::CloseSystem()
}
}
bool CN64System::EmulationStarting(void * hThread, uint32_t ThreadId)
bool CN64System::EmulationStarting(CThread * thread)
{
WriteTrace(TraceN64System, TraceDebug, "Starting (hThread: %p ThreadId: %d)", hThread, ThreadId);
WriteTrace(TraceN64System, TraceDebug, "Starting (hThread: %p ThreadId: %d)", thread, thread->ThreadID());
bool bRes = true;
WriteTrace(TraceN64System, TraceDebug, "Setting N64 system as active");
if (g_BaseSystem->SetActiveSystem(true))
{
g_BaseSystem->m_CPU_Handle = hThread;
g_BaseSystem->m_CPU_ThreadID = ThreadId;
g_BaseSystem->m_thread = thread;
WriteTrace(TraceN64System, TraceDebug, "Setting up N64 system done");
g_Settings->SaveBool(GameRunning_LoadingInProgress, false);
try
@ -975,7 +970,6 @@ void CN64System::CpuStopped()
{
m_SyncCPU->CpuStopped();
}
m_CPU_Handle = NULL;
WriteTrace(TraceN64System, TraceDebug, "Done");
}

View File

@ -11,6 +11,7 @@
#pragma once
#include <Common/SyncEvent.h>
#include <Common/Thread.h>
#include <Project64-core/Settings/N64SystemSettings.h>
#include <Project64-core/N64System/ProfilingClass.h>
#include <Project64-core/N64System/Recompiler/RecompilerClass.h>
@ -103,14 +104,8 @@ private:
friend CSystemTimer;
//Used for loading and potentially executing the CPU in its own thread.
struct ThreadInfo
{
void** ThreadHandle;
uint32_t ThreadID;
};
static void StartEmulationThread(ThreadInfo * Info);
static bool EmulationStarting(void * hThread, uint32_t ThreadId);
static void StartEmulationThread(CThread * thread);
static bool EmulationStarting(CThread * thread);
static void StartEmulationThead();
void ExecuteCPU();
@ -166,8 +161,7 @@ private:
int32_t m_CyclesToSkip;
//Handle to the cpu thread
void * m_CPU_Handle;
uint32_t m_CPU_ThreadID;
CThread * m_thread;
//Handle to pause mutex
SyncEvent m_hPauseEvent;