Updated timer subsystem
This commit is contained in:
parent
2020fe2123
commit
62dfa7b4e2
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
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");
|
||||
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -58,6 +58,9 @@ static std::vector<TimerObject*> TimerList;
|
|||
// Lock to acquire when accessing TimerList
|
||||
std::mutex TimerMtx;
|
||||
|
||||
// Forward declare
|
||||
void InitXboxThread(DWORD_PTR cores);
|
||||
|
||||
|
||||
// Returns the current time of the timer
|
||||
inline uint64_t GetTime_NS(TimerObject* 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
|
||||
|
@ -103,7 +106,15 @@ 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;
|
||||
|
@ -140,6 +151,8 @@ TimerObject* Timer_Create(pTimerCB Callback, void* Arg)
|
|||
pTimer->ExpireTime_MS.store(0);
|
||||
pTimer->Exit.store(false);
|
||||
pTimer->Opaque = Arg;
|
||||
Name.empty() ? pTimer->Name = "Unnamed thread" : pTimer->Name = Name;
|
||||
pTimer->CpuAffinity = Affinity;
|
||||
TimerList.emplace_back(pTimer);
|
||||
|
||||
return pTimer;
|
||||
|
|
|
@ -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
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue