VirtualC64 v5.0 beta
Commodore 64 Emulator
Loading...
Searching...
No Matches
Thread.h
Go to the documentation of this file.
1// -----------------------------------------------------------------------------
2// This file is part of VirtualC64
3//
4// Copyright (C) Dirk W. Hoffmann. www.dirkwhoffmann.de
5// This FILE is dual-licensed. You are free to choose between:
6//
7// - The GNU General Public License v3 (or any later version)
8// - The Mozilla Public License v2
9//
10// SPDX-License-Identifier: GPL-3.0-or-later OR MPL-2.0
11// -----------------------------------------------------------------------------
13
14#pragma once
15
16#include "ThreadTypes.h"
17#include "CoreComponent.h"
18#include "Chrono.h"
19#include "Wakeable.h"
20
21namespace vc64 {
22
29
35class Thread : public CoreObject, public Suspendable, public Wakeable {
36
37protected:
38
39 // The thread object
40 std::thread thread;
41
42 // The current thread state and a change request
43 ExecState state = STATE_UNINIT;
44 ExecState newState = STATE_UNINIT;
45 std::atomic_flag stateChangeRequest {};
46
47 // Warp and track state
48 u8 warp = 0;
49 u8 track = 0;
50
51 // Counters
52 isize suspendCounter = 0;
53 isize frameCounter = 0;
54 isize statsCounter = 0;
55
56 // Time stamps
57 util::Time baseTime;
58
59 // Clocks for measuring the CPU load
60 util::Clock nonstopClock;
61 util::Clock loadClock;
62
63 // Statistical information (CPU load, frames per second, thread resyncs)
64 double cpuLoad = 0.0;
65 double fps = 0.0;
66 isize resyncs = 0;
67
68 // Debug clocks
69 util::Clock wakeupClock;
70
71
72 //
73 // Initializing
74 //
75
76public:
77
78 Thread();
79 ~Thread();
80
81 const char *objectName() const override { return "Thread"; }
82
83 // Checks the launch state
84 bool isLaunched() const { return thread.joinable(); }
85
86protected:
87
88 // Launches the emulator thread
89 void launch();
90
91 // Sanity check
92 void assertLaunched();
93
94
95 //
96 // Executing
97 //
98
99public:
100
101 // Returns true if this functions is called from within the emulator thread
102 bool isEmulatorThread() const { return std::this_thread::get_id() == thread.get_id(); }
103
104 // Performs a state change
105 void switchState(ExecState newState);
106
107private:
108
109 // Updates the emulator state (implemented by the subclass)
110 virtual void update() = 0;
111
112 // Computes the number of overdue frames (provided by the subclass)
113 virtual isize missingFrames() const = 0;
114
115 // Target frame rate of this thread (provided by the subclass)
116 virtual double refreshRate() const = 0;
117
118 // The code to be executed in each iteration (implemented by the subclass)
119 virtual void computeFrame() = 0;
120
121 // Rectifies an out-of-sync condition. Resets all counters and clocks.
122 void resync();
123
128 void runLoop();
129
130 // Computes all missing frames
131 void execute();
132
133 // Suspends the thread till the next wakeup pulse
134 void sleep();
135
136
137 //
138 // Analyzing
139 //
140
141private:
142
143 void computeStats();
144
145
146 //
147 // Managing states
148 //
149
150public:
151
155 void suspend() override;
156
160 void resume() override;
161
162 bool isPoweredOn() const { return state != STATE_OFF; }
163 bool isPoweredOff() const { return state == STATE_OFF; }
164 bool isPaused() const { return state == STATE_PAUSED; }
165 bool isRunning() const { return state == STATE_RUNNING; }
166 bool isSuspended() const { return state == STATE_SUSPENDED; }
167 bool isHalted() const { return state == STATE_HALTED; }
168 bool isWarping() const { return warp != 0; }
169 bool isTracking() const { return track != 0; }
170
171 void powerOn();
172 void powerOff();
173 void run() throws;
174 void pause();
175 void halt();
176
177 void warpOn(isize source = 0);
178 void warpOff(isize source = 0);
179 void trackOn(isize source = 0);
180 void trackOff(isize source = 0);
181
182 // Signals a state transition
183 virtual void _powerOn() = 0;
184 virtual void _powerOff() = 0;
185 virtual void _pause() = 0;
186 virtual void _run() = 0;
187 virtual void _halt() = 0;
188 virtual void _warpOn() = 0;
189 virtual void _warpOff() = 0;
190 virtual void _trackOn() = 0;
191 virtual void _trackOff() = 0;
192
193private:
194
195 // Initiates a state change
196 void changeStateTo(ExecState requestedState);
197
198 // Returns if the emulator is ready to runs, throws an exception otherwise
199 virtual void isReady() throws = 0;
200
201
202 //
203 // Synchronizing
204 //
205
206public:
207
211 void wakeUp();
212
213 // Wait until the thread has terminated
214 void join() { if (thread.joinable()) thread.join(); }
215};
216
219}
Suspend-resume mechanism.
Definition Suspendable.h:20
Implements the emulator's state model.
Definition Thread.h:35
void wakeUp()
Awakes the thread.
Definition Thread.cpp:401
void resume() override
Resumes the thread.
Definition Thread.cpp:427
void suspend() override
Suspends the thread.
Definition Thread.cpp:408
VirtualC64 project namespace.
Definition CmdQueue.cpp:16
EXEC_STATE
Execution state.
Definition ThreadTypes.h:22
@ STATE_UNINIT
Not yet initialized.
Definition ThreadTypes.h:23
@ STATE_OFF
Powered off.
Definition ThreadTypes.h:24
@ STATE_PAUSED
Powered on, but currently paused.
Definition ThreadTypes.h:25
@ STATE_HALTED
Shut down.
Definition ThreadTypes.h:28
@ STATE_SUSPENDED
Shortly paused for an internal state change.
Definition ThreadTypes.h:27
@ STATE_RUNNING
Up and running.
Definition ThreadTypes.h:26
util::Exception StateChangeException
Requests a state change from within the emulator.
Definition Thread.h:28
Base class for all emulator exceptions.
Definition Exception.h:22