Motion Master 6.0.0-alpha.86
Next-generation motion control software
Loading...
Searching...
No Matches
game_loop.h
Go to the documentation of this file.
1#pragma once
2
3#include <atomic>
4#include <chrono>
5#include <cstdint>
6#include <nlohmann/json_fwd.hpp>
7#include <vector>
8
9#include "core/cyclic_task.h"
10#include "node/device_manager.h"
11
16 uint64_t periodUs = 0;
17 double targetHz = 0.0;
18 double achievedHz = 0.0;
19 uint64_t executedCycles = 0;
20 uint64_t skippedCycles = 0;
21 uint64_t lastExecNs = 0;
22 uint64_t maxExecNs = 0;
23 uint64_t avgExecNs = 0;
24 bool schedFifo = false;
25 bool memLocked = false;
26 int cpuAffinity = -1;
27 bool cpuPinned = false;
28 uint64_t timestampUs = 0;
29};
30
32void to_json(nlohmann::json& j, const GameLoopHealth& h);
33
47class GameLoop {
48 public:
63 GameLoop(mm::node::DeviceManager& deviceManager, std::chrono::microseconds period,
64 int cpuAffinity = -1);
65
68 ~GameLoop() = default;
69
72 GameLoop(const GameLoop&) = delete;
74 GameLoop& operator=(const GameLoop&) = delete;
75
89 void addTask(mm::core::CyclicTask* task);
90
103 void run();
104
108 void stop();
109
130 void setPeriod(std::chrono::microseconds period);
131
142 uint64_t executedCycles() const;
143
156 uint64_t skippedCycles() const;
157
163 GameLoopHealth health() const;
164
165 private:
166 // Cycle period; read by the RT loop each iteration, written by setPeriod from another thread.
167 // std::chrono::microseconds is an 8-byte trivially-copyable type, so this atomic is lock-free.
168 std::atomic<std::chrono::microseconds> period_;
169 std::atomic<bool> running_{false};
170 std::atomic<uint64_t> executedCycles_{0};
171 std::atomic<uint64_t> skippedCycles_{0};
172 std::atomic<uint64_t> lastExecNs_{0}; // most recent cycle's task-execution time
173 std::atomic<uint64_t> maxExecNs_{0}; // worst task-execution time since run()
174 std::atomic<uint64_t> sumExecNs_{0}; // running sum → avg = sum / executedCycles
175 std::atomic<uint64_t> startMonoNs_{0}; // steady_clock ns at run() start; 0 until then
176 std::atomic<bool> schedFifo_{false}; // SCHED_FIFO acquired in run()
177 std::atomic<bool> memLocked_{false}; // mlockall succeeded in run()
178 std::atomic<bool> cpuPinned_{false}; // affinity applied in run()
179 const int cpuAffinity_; // core to pin to; < 0 = leave unpinned
180 // The cycle the loop enters before calling any task. Held for the whole task list, so a task's
181 // device and parameter lookups stay valid without the task naming the guard at all.
182 mm::node::DeviceManager& deviceManager_;
183 std::vector<mm::core::CyclicTask*> tasks_;
184};
Fixed-period real-time loop.
Definition game_loop.h:47
GameLoopHealth health() const
Returns a snapshot of real-time loop health for diagnostics.
Definition game_loop.cc:143
uint64_t skippedCycles() const
Returns the total number of cycles skipped since run() was called.
Definition game_loop.cc:141
~GameLoop()=default
Destructor. Does not call stop() — the caller is responsible for stopping the loop before destroying ...
uint64_t executedCycles() const
Returns the number of cycles actually executed since run() was called.
Definition game_loop.cc:137
GameLoop(const GameLoop &)=delete
Copying is deleted — the loop owns real-time scheduling state that cannot be shared.
void run()
Blocks the calling thread, running one cycle per period until stop() is called.
Definition game_loop.cc:35
void addTask(mm::core::CyclicTask *task)
Registers a task to be executed every cycle.
Definition game_loop.cc:33
GameLoop & operator=(const GameLoop &)=delete
Copy assignment is deleted — see copy constructor.
void setPeriod(std::chrono::microseconds period)
Changes the cycle period while the loop is running.
Definition game_loop.cc:133
void stop()
Signals the loop to stop after the current cycle completes.
Definition game_loop.cc:131
Interface for work executed once per game loop cycle.
Definition cyclic_task.h:44
Owns the fieldbus driver and node collection, and drives PDO exchange.
Definition device_manager.h:287
void to_json(nlohmann::json &j, const GameLoopHealth &h)
Serializes a GameLoopHealth to JSON (found via ADL by nlohmann::json).
Definition game_loop.cc:168
Snapshot of game-loop real-time health for the GET /api/game-loop diagnostic endpoint....
Definition game_loop.h:15
bool schedFifo
SCHED_FIFO acquired (false on Windows / failure).
Definition game_loop.h:24
uint64_t avgExecNs
Mean task-exec time since run() (ns).
Definition game_loop.h:23
uint64_t periodUs
Configured target period (µs).
Definition game_loop.h:16
double targetHz
Target rate = 1e6 / periodUs.
Definition game_loop.h:17
uint64_t timestampUs
Server stamp (epoch µs) for exact client Δt.
Definition game_loop.h:28
uint64_t lastExecNs
Task-exec time of the most recent cycle (ns).
Definition game_loop.h:21
double achievedHz
Cumulative avg = executedCycles / uptime; 0 pre-run.
Definition game_loop.h:18
uint64_t skippedCycles
Cycles skipped to catch up since run().
Definition game_loop.h:20
uint64_t maxExecNs
Worst task-exec time since run() (ns).
Definition game_loop.h:22
int cpuAffinity
Core the RT thread was asked to pin to; -1 = not requested.
Definition game_loop.h:26
bool cpuPinned
Pin took. With cpuAffinity >= 0 and this false, it failed.
Definition game_loop.h:27
bool memLocked
mlockall ok (Linux only; false elsewhere).
Definition game_loop.h:25
uint64_t executedCycles
Loop iterations run since run().
Definition game_loop.h:19