mirror of https://github.com/stella-emu/stella.git
Scheduling fixes.
This commit is contained in:
parent
d8732c9378
commit
ea94f5e795
|
@ -175,6 +175,7 @@ void EmulationWorker::handleWakeupFromWaitingForResume(std::unique_lock<std::mut
|
||||||
switch (myPendingSignal) {
|
switch (myPendingSignal) {
|
||||||
case Signal::resume:
|
case Signal::resume:
|
||||||
myPendingSignal = Signal::none;
|
myPendingSignal = Signal::none;
|
||||||
|
myVirtualTime = high_resolution_clock::now();
|
||||||
dispatchEmulation(lock);
|
dispatchEmulation(lock);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -202,10 +203,10 @@ void EmulationWorker::handleWakeupFromWaitingForStop(std::unique_lock<std::mutex
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Signal::none:
|
case Signal::none:
|
||||||
if (myWakeupPoint <= high_resolution_clock::now())
|
if (myVirtualTime <= high_resolution_clock::now())
|
||||||
dispatchEmulation(lock);
|
dispatchEmulation(lock);
|
||||||
else
|
else
|
||||||
mySignalCondition.wait_until(lock, myWakeupPoint);
|
mySignalCondition.wait_until(lock, myVirtualTime);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -222,7 +223,6 @@ void EmulationWorker::dispatchEmulation(std::unique_lock<std::mutex>& lock)
|
||||||
{
|
{
|
||||||
myState = State::running;
|
myState = State::running;
|
||||||
|
|
||||||
time_point<high_resolution_clock> now = high_resolution_clock::now();
|
|
||||||
uInt64 totalCycles = 0;
|
uInt64 totalCycles = 0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
@ -232,13 +232,13 @@ void EmulationWorker::dispatchEmulation(std::unique_lock<std::mutex>& lock)
|
||||||
if (myDispatchResult->getStatus() == DispatchResult::Status::ok) {
|
if (myDispatchResult->getStatus() == DispatchResult::Status::ok) {
|
||||||
// If emulation finished successfully, we can go for another round
|
// If emulation finished successfully, we can go for another round
|
||||||
duration<double> timesliceSeconds(static_cast<double>(totalCycles) / static_cast<double>(myCyclesPerSecond));
|
duration<double> timesliceSeconds(static_cast<double>(totalCycles) / static_cast<double>(myCyclesPerSecond));
|
||||||
myWakeupPoint = now + duration_cast<high_resolution_clock::duration>(timesliceSeconds);
|
myVirtualTime += duration_cast<high_resolution_clock::duration>(timesliceSeconds);
|
||||||
|
|
||||||
myState = State::waitingForStop;
|
myState = State::waitingForStop;
|
||||||
|
|
||||||
if (myWakeupPoint > high_resolution_clock::now())
|
if (myVirtualTime > high_resolution_clock::now())
|
||||||
// If we can keep up with the emulation, we sleep
|
// If we can keep up with the emulation, we sleep
|
||||||
mySignalCondition.wait_until(lock, myWakeupPoint);
|
mySignalCondition.wait_until(lock, myVirtualTime);
|
||||||
else {
|
else {
|
||||||
// If we are already lagging behind, we briefly relinquish control over the mutex
|
// If we are already lagging behind, we briefly relinquish control over the mutex
|
||||||
// and yield to scheduler, to make sure that the main thread has a chance to stop us
|
// and yield to scheduler, to make sure that the main thread has a chance to stop us
|
||||||
|
|
|
@ -84,7 +84,7 @@ class EmulationWorker
|
||||||
uInt32 myMinCycles;
|
uInt32 myMinCycles;
|
||||||
DispatchResult* myDispatchResult;
|
DispatchResult* myDispatchResult;
|
||||||
|
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> myWakeupPoint;
|
std::chrono::time_point<std::chrono::high_resolution_clock> myVirtualTime;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // EMULATION_WORKER_HXX
|
#endif // EMULATION_WORKER_HXX
|
||||||
|
|
Loading…
Reference in New Issue