Updated timer subsystem

This commit is contained in:
ergo720 2019-01-08 00:13:26 +01:00
parent 2020fe2123
commit 62dfa7b4e2
5 changed files with 43 additions and 22 deletions

View File

@ -685,7 +685,7 @@ static unsigned int WINAPI CxbxKrnlInterruptThread(PVOID param)
return 0;
}
static void CxbxKrnlClockThread()
static unsigned int CxbxKrnlClockThread(void* pVoid)
{
LARGE_INTEGER CurrentTicks;
uint64_t Delta;
@ -708,7 +708,7 @@ static void CxbxKrnlClockThread()
Delta = CurrentTicks.QuadPart - LastTicks;
LastTicks = CurrentTicks.QuadPart;
Error += (Delta * SCALE_US_IN_S);
Error += (Delta * SCALE_S_IN_US);
Microseconds = Error / HostClockFrequency;
Error -= (Microseconds * HostClockFrequency);
@ -719,6 +719,8 @@ static void CxbxKrnlClockThread()
UnaccountedMicroseconds -= (IncrementScaling * 1000);
xboxkrnl::KiClockIsr(IncrementScaling);
return 0;
}
std::vector<xbaddr> g_RdtscPatches;
@ -1641,6 +1643,9 @@ __declspec(noreturn) void CxbxKrnlInit
// Create the interrupt processing thread
DWORD dwThreadId;
HANDLE hThread = (HANDLE)_beginthreadex(NULL, NULL, CxbxKrnlInterruptThread, NULL, NULL, (uint*)&dwThreadId);
// Start the kernel clock thread
TimerObject* KernelClockThr = Timer_Create(CxbxKrnlClockThread, nullptr, "Kernel clock thread", &g_CPUOthers);
Timer_Start(KernelClockThr, SCALE_MS_IN_NS);
DBG_PRINTF_EX(LOG_PREFIX_INIT, "Calling XBE entry point...\n");
CxbxLaunchXbe(Entry);

View File

@ -234,9 +234,10 @@ OHCI::OHCI(USBDevice* UsbObj)
OHCI_StateReset();
}
void OHCI::OHCI_FrameBoundaryWrapper(void* pVoid)
unsigned int OHCI::OHCI_FrameBoundaryWrapper(void* pVoid)
{
static_cast<OHCI*>(pVoid)->OHCI_FrameBoundaryWorker();
static_cast<OHCI*>(pVoid)->OHCI_FrameBoundaryWorker();
return 0;
}
void OHCI::OHCI_FrameBoundaryWorker()
@ -894,7 +895,7 @@ void OHCI::OHCI_StateReset()
void OHCI::OHCI_BusStart()
{
// Create the EOF timer.
m_pEOFtimer = Timer_Create(OHCI_FrameBoundaryWrapper, this);
m_pEOFtimer = Timer_Create(OHCI_FrameBoundaryWrapper, this, "", nullptr);
DBG_PRINTF("Operational mode event\n");

View File

@ -183,7 +183,7 @@ class OHCI
int m_AsyncComplete = 0;
// EOF callback wrapper
static void OHCI_FrameBoundaryWrapper(void* pVoid);
static unsigned int OHCI_FrameBoundaryWrapper(void* pVoid);
// EOF callback function
void OHCI_FrameBoundaryWorker();
// inform the HCD that we got a problem here...

View File

@ -56,7 +56,10 @@
// Vector storing all the timers created
static std::vector<TimerObject*> TimerList;
// Lock to acquire when accessing TimerList
std::mutex TimerMtx;
std::mutex TimerMtx;
// Forward declare
void InitXboxThread(DWORD_PTR cores);
// Returns the current time of the timer
@ -65,11 +68,11 @@ inline uint64_t GetTime_NS(TimerObject* Timer)
#ifdef _WIN32
LARGE_INTEGER li;
QueryPerformanceCounter(&li);
uint64_t Ret = Muldiv64(li.QuadPart, SCALE_NS_IN_S, HostClockFrequency);
uint64_t Ret = Muldiv64(li.QuadPart, SCALE_S_IN_NS, HostClockFrequency);
#elif __linux__
static struct timespec ts;
clock_gettime(CLOCK_MONOTONIC_RAW, &ts);
uint64_t Ret = Muldiv64(ts.tv_sec, SCALE_NS_IN_S, 1) + ts.tv_nsec;
uint64_t Ret = Muldiv64(ts.tv_sec, SCALE_S_IN_NS, 1) + ts.tv_nsec;
#else
#error "Unsupported OS"
#endif
@ -102,8 +105,16 @@ void Timer_Destroy(TimerObject* Timer)
// Thread that runs the timer
void ClockThread(TimerObject* Timer)
{
uint64_t NewExpireTime = GetNextExpireTime(Timer);
{
uint64_t NewExpireTime;
if (!Timer->Name.empty()) {
CxbxSetThreadName(Timer->Name.c_str());
}
if (Timer->CpuAffinity != nullptr) {
InitXboxThread(*Timer->CpuAffinity);
}
NewExpireTime = GetNextExpireTime(Timer);
while (true) {
if (GetTime_NS(Timer) > NewExpireTime) {
@ -131,7 +142,7 @@ void Timer_Exit(TimerObject* Timer)
}
// Allocates the memory for the timer object
TimerObject* Timer_Create(pTimerCB Callback, void* Arg)
TimerObject* Timer_Create(TimerCB Callback, void* Arg, std::string Name, unsigned long* Affinity)
{
std::lock_guard<std::mutex>lock(TimerMtx);
TimerObject* pTimer = new TimerObject;
@ -139,7 +150,9 @@ TimerObject* Timer_Create(pTimerCB Callback, void* Arg)
pTimer->Callback = Callback;
pTimer->ExpireTime_MS.store(0);
pTimer->Exit.store(false);
pTimer->Opaque = Arg;
pTimer->Opaque = Arg;
Name.empty() ? pTimer->Name = "Unnamed thread" : pTimer->Name = Name;
pTimer->CpuAffinity = Affinity;
TimerList.emplace_back(pTimer);
return pTimer;

View File

@ -39,24 +39,26 @@
#include <atomic>
#define SCALE_NS_IN_S 1000000000
#define SCALE_NS_IN_MS 1000000
#define SCALE_NS_IN_US 1000
#define SCALE_S_IN_NS 1000000000
#define SCALE_MS_IN_NS 1000000
#define SCALE_US_IN_NS 1000
#define SCALE_NS_IN_NS 1
#define SCALE_US_IN_S 1000000
#define SCALE_US_IN_MS 1000
#define SCALE_S_IN_US 1000000
#define SCALE_MS_IN_US 1000
#define SCALE_US_IN_US 1
/* typedef of the timer object and the callback function */
typedef void(*pTimerCB)(void*);
typedef unsigned int(*TimerCB)(void*);
typedef struct _TimerObject
{
int Type; // timer type
std::atomic_uint64_t ExpireTime_MS; // when the timer expires (ms)
std::atomic_bool Exit; // indicates that the timer should be destroyed
pTimerCB Callback; // function to call when the timer expires
void* Opaque; // opaque argument to pass to the callback
TimerCB Callback; // function to call when the timer expires
void* Opaque; // opaque argument to pass to the callback
std::string Name; // the name of the timer thread (if any)
unsigned long* CpuAffinity; // the cpu affinity of the timer thread (if any)
}
TimerObject;
@ -64,7 +66,7 @@ TimerObject;
uint64_t HostClockFrequency;
/* Timer exported functions */
TimerObject* Timer_Create(pTimerCB Callback, void* Arg);
TimerObject* Timer_Create(TimerCB Callback, void* Arg, std::string Name, unsigned long* Affinity);
void Timer_Start(TimerObject* Timer, uint64_t Expire_MS);
void Timer_Exit(TimerObject* Timer);
void Timer_ChangeExpireTime(TimerObject* Timer, uint64_t Expire_ms);