mirror of https://github.com/stella-emu/stella.git
Enable RT loop.
This commit is contained in:
parent
f03435f1a9
commit
7b6ba75b7a
|
@ -598,6 +598,9 @@ class OSystem
|
|||
// Indicates whether to stop the main loop
|
||||
bool myQuitLoop{false};
|
||||
|
||||
static constexpr uInt32 FPS_METER_QUEUE_SIZE = 100;
|
||||
FpsMeter myFpsMeter{FPS_METER_QUEUE_SIZE};
|
||||
|
||||
private:
|
||||
FSNode myBaseDir, myStateDir, mySnapshotSaveDir, mySnapshotLoadDir,
|
||||
myNVRamDir, myCfgDir, myHomeDir, myUserDir, myBezelDir;
|
||||
|
@ -607,9 +610,6 @@ class OSystem
|
|||
string myFeatures;
|
||||
string myBuildInfo;
|
||||
|
||||
static constexpr uInt32 FPS_METER_QUEUE_SIZE = 100;
|
||||
FpsMeter myFpsMeter{FPS_METER_QUEUE_SIZE};
|
||||
|
||||
// If not empty, a hint for derived classes to use this as the
|
||||
// base directory (where all settings are stored)
|
||||
// Derived classes are free to ignore it and use their own defaults
|
||||
|
|
|
@ -5,6 +5,13 @@
|
|||
#include <sys/sysinfo.h>
|
||||
|
||||
#include "Logger.hxx"
|
||||
#include "RTEmulationWorker.hxx"
|
||||
#include "EventHandler.hxx"
|
||||
#include "TimerManager.hxx"
|
||||
#include "DispatchResult.hxx"
|
||||
#include "Console.hxx"
|
||||
#include "Debugger.hxx"
|
||||
#include "TIA.hxx"
|
||||
|
||||
namespace {
|
||||
void configureScheduler() {
|
||||
|
@ -34,3 +41,73 @@ bool OSystemRTStella::initialize(const Settings::Options& options)
|
|||
|
||||
return OSystemStandalone::initialize(options);
|
||||
}
|
||||
|
||||
void OSystemRTStella::mainLoop()
|
||||
{
|
||||
RTEmulationWorker worker;
|
||||
DispatchResult dispatchResult;
|
||||
|
||||
for (;;) {
|
||||
TIA& tia = myConsole->tia();
|
||||
|
||||
if (worker.isRunning()) worker.suspend();
|
||||
|
||||
const EventHandlerState oldState = myEventHandler->state();
|
||||
const bool workerWasRunning = worker.isRunning();
|
||||
|
||||
if (oldState == EventHandlerState::EMULATION && worker.isRunning()) {
|
||||
tia.renderToFrameBuffer();
|
||||
|
||||
switch (dispatchResult.getStatus()) {
|
||||
case DispatchResult::Status::ok:
|
||||
break;
|
||||
|
||||
case DispatchResult::Status::debugger:
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myDebugger->start(
|
||||
dispatchResult.getMessage(),
|
||||
dispatchResult.getAddress(),
|
||||
dispatchResult.wasReadTrap(),
|
||||
dispatchResult.getToolTip()
|
||||
);
|
||||
#endif
|
||||
|
||||
break;
|
||||
|
||||
case DispatchResult::Status::fatal:
|
||||
#ifdef DEBUGGER_SUPPORT
|
||||
myDebugger->startWithFatalError(dispatchResult.getMessage());
|
||||
#else
|
||||
cerr << dispatchResult.getMessage() << endl;
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
cout << (int)dispatchResult.getStatus() << endl << std::flush;
|
||||
throw runtime_error("invalid emulation dispatch result");
|
||||
}
|
||||
}
|
||||
|
||||
myEventHandler->poll(TimerManager::getTicks());
|
||||
if (myQuitLoop) break;
|
||||
|
||||
if (dispatchResult.getStatus() == DispatchResult::Status::ok && myEventHandler->frying() && worker.isRunning())
|
||||
myConsole->fry();
|
||||
|
||||
const EventHandlerState newState = myEventHandler->state();
|
||||
|
||||
if (newState == EventHandlerState::EMULATION && !worker.isRunning()) {
|
||||
worker.start(myConsole->emulationTiming().cyclesPerSecond(), &dispatchResult, &tia);
|
||||
myFpsMeter.reset();
|
||||
} else if (newState != EventHandlerState::EMULATION && worker.isRunning()) {
|
||||
worker.stop();
|
||||
} else if (newState == EventHandlerState::EMULATION && worker.isRunning()) {
|
||||
worker.resume();
|
||||
}
|
||||
|
||||
if (oldState == EventHandlerState::EMULATION && workerWasRunning)
|
||||
myFrameBuffer->updateInEmulationMode(myFpsMeter.fps());
|
||||
else
|
||||
myFrameBuffer->update();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,6 +23,8 @@
|
|||
class OSystemRTStella: public OSystemStandalone {
|
||||
public:
|
||||
bool initialize(const Settings::Options& options) override;
|
||||
|
||||
void mainLoop() override;
|
||||
};
|
||||
|
||||
#endif // OSYSTEM_RTSTELLA_HXX
|
||||
|
|
|
@ -15,12 +15,15 @@
|
|||
#define TRACE_MSG(m) m " in " STRINGIFY(__FILE__) ":" STRINGIFY(__LINE__)
|
||||
|
||||
namespace {
|
||||
constexpr uint64_t TIMESLICE_NANOSECONDS = 100000;
|
||||
constexpr uint64_t MAX_LAG_NANOSECONDS = 10 * TIMESLICE_NANOSECONDS;
|
||||
constexpr uint64_t TIMESLICE_NANOSECONDS = 1000000;
|
||||
constexpr uint64_t MAX_LAG_NANOSECONDS = 100000000;
|
||||
|
||||
inline Int64 timeDifferenceNanoseconds(const struct timespec& from, const struct timespec& to)
|
||||
{
|
||||
return (from.tv_sec - to.tv_sec) * 1000000000 + (from.tv_nsec - to.tv_nsec);
|
||||
uInt64 deltaSec = from.tv_sec - to.tv_sec;
|
||||
uInt64 deltaNsec = from.tv_nsec - to.tv_nsec;
|
||||
|
||||
return deltaSec * 1000000000 + deltaNsec;
|
||||
}
|
||||
|
||||
void configureScheduler() {
|
||||
|
@ -119,6 +122,8 @@ void RTEmulationWorker::suspend()
|
|||
|
||||
// the thread may transition to State::exception instead, so make sure that we rethrow
|
||||
while (myState != State::paused) rethrowPendingException();
|
||||
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -133,6 +138,8 @@ void RTEmulationWorker::resume()
|
|||
|
||||
// the thread may transition to State::exception instead, so make sure that we rethrow
|
||||
while (myState != State::running) rethrowPendingException();
|
||||
|
||||
__sync_synchronize();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -207,6 +214,7 @@ void RTEmulationWorker::stop()
|
|||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void RTEmulationWorker::threadMain()
|
||||
{
|
||||
configureScheduler();
|
||||
|
@ -260,6 +268,8 @@ void RTEmulationWorker::dispatchEmulation()
|
|||
|
||||
clock_gettime(CLOCK_MONOTONIC, &timeOffset);
|
||||
|
||||
myDispatchResult->setOk(0);
|
||||
|
||||
myState = State::running;
|
||||
myPendingSignal = Signal::none;
|
||||
|
||||
|
|
|
@ -64,6 +64,16 @@ class RTEmulationWorker {
|
|||
|
||||
void stop();
|
||||
|
||||
State state()
|
||||
{
|
||||
return myState;
|
||||
}
|
||||
|
||||
bool isRunning()
|
||||
{
|
||||
return myState == State::running || myState == State::paused;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
void threadMain();
|
||||
|
|
Loading…
Reference in New Issue