Use a condition variable to notify interrupts, fixes stuttering in the dashboard

This commit is contained in:
ergo720 2022-02-18 19:06:39 +01:00
parent bc98e164b2
commit c6ea72dcf4
3 changed files with 14 additions and 17 deletions

View File

@ -51,6 +51,8 @@ xbox::PLIST_ENTRY RemoveTailList(xbox::PLIST_ENTRY pListHead);
extern xbox::LAUNCH_DATA_PAGE DefaultLaunchDataPage;
extern xbox::PKINTERRUPT EmuInterruptList[MAX_BUS_INTERRUPT_LEVEL + 1];
inline std::condition_variable g_InterruptSignal;
inline std::atomic_bool g_AnyInterruptAsserted = false;
class HalSystemInterrupt {
public:
@ -61,6 +63,8 @@ public:
}
m_Asserted = state;
g_AnyInterruptAsserted = true;
g_InterruptSignal.notify_one();
};
void Enable() {

View File

@ -336,17 +336,6 @@ void InitSoftwareInterrupts()
}
#endif
void TriggerPendingConnectedInterrupts()
{
for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) {
// If the interrupt is pending and connected, process it
if (HalSystemInterrupts[i].IsPending() && EmuInterruptList[i] && EmuInterruptList[i]->Connected) {
HalSystemInterrupts[i].Trigger(EmuInterruptList[i]);
}
SwitchToThread();
}
}
static xbox::void_xt NTAPI CxbxKrnlInterruptThread(xbox::PVOID param)
{
CxbxSetThreadName("CxbxKrnl Interrupts");
@ -355,11 +344,17 @@ static xbox::void_xt NTAPI CxbxKrnlInterruptThread(xbox::PVOID param)
InitSoftwareInterrupts();
#endif
std::mutex m;
std::unique_lock<std::mutex> lock(m);
while (true) {
if (g_bEnableAllInterrupts) {
TriggerPendingConnectedInterrupts();
for (int i = 0; i < MAX_BUS_INTERRUPT_LEVEL; i++) {
// If the interrupt is pending and connected, process it
if (HalSystemInterrupts[i].IsPending() && EmuInterruptList[i] && EmuInterruptList[i]->Connected) {
HalSystemInterrupts[i].Trigger(EmuInterruptList[i]);
}
}
Sleep(1);
g_InterruptSignal.wait(lock, []() { return g_AnyInterruptAsserted.load() && g_bEnableAllInterrupts.load(); });
g_AnyInterruptAsserted = false;
}
assert(0);

View File

@ -150,8 +150,6 @@ static void update_irq(NV2AState *d)
else {
HalSystemInterrupts[3].Assert(false);
}
SwitchToThread();
}
@ -1117,7 +1115,7 @@ static void nv2a_vblank_thread(NV2AState *d)
//NV2ADevice::UpdateHostDisplay(d);
}
Sleep(1);
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}