-
Notifications
You must be signed in to change notification settings - Fork 25
/
main.cc
99 lines (78 loc) · 3.17 KB
/
main.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#include <cactus_rt/rt.h>
#include <chrono>
#include <iostream>
using cactus_rt::App;
using cactus_rt::CyclicThread;
/**
* This is a thread that loops at 1 kHz. We always inherit from CyclicThread if
* we want a thread that executes periodically.
*
* In this thread, we need to make sure we construct the cactus_rt::CyclicThread
* object as a part of the constructor to initialize the thread. To write code
* that executes at 1000 Hz, override and implement the Loop() function.
*
* This class demonstrates how it is done.
*/
class ExampleRTThread : public CyclicThread {
public:
/**
* @brief Construct the thread. Note we are initializing the creating the
* CyclicThread here with a predetermined name and config (via MakeConfig()).
*/
ExampleRTThread() : CyclicThread("ExampleRTThread", MakeConfig()) {}
protected:
/**
* @brief This methods runs every loop, which for this particular example is every 1ms.
*
* @param elapsed_ns The number of nanoseconds elapsed since the App::Start was called.
* @return LoopControl::Continue if you want the thread to continue
* @return LoopControl::Stop if you want to thread to stop
*/
LoopControl Loop(int64_t elapsed_ns) noexcept final {
// Code written in this function executes every 1 ms.
// This demonstrates the usage of the quill logger. This emits a log message every 1s.
LOG_INFO_LIMIT(std::chrono::seconds(1), Logger(), "Looping for {}", std::chrono::nanoseconds(elapsed_ns));
// Return LoopControl::Stop if you want the thread to stop.
return LoopControl::Continue;
}
private:
/**
* @brief Creates a CyclicThreadConfig object which configures this thread.
*/
static cactus_rt::CyclicThreadConfig MakeConfig() {
// This function sets up the thread configuration for this thread.
cactus_rt::CyclicThreadConfig config;
// Run at 1000 Hz.
config.period_ns = 1'000'000;
// Pin this thread on CPU core #2. If you don't want to pin in on a CPU core,
// remove the following line.
config.cpu_affinity = std::vector<size_t>{2};
// Run the thread with SCHED_FIFO at real-time priority of 80.
config.SetFifoScheduler(80);
return config;
}
};
int main() {
// Sets up the signal handlers for SIGINT and SIGTERM (by default).
cactus_rt::SetUpTerminationSignalHandler();
// We first create cactus_rt App object.
App app;
// We then create a thread object. Threads should always be created via the
// App::CreateThread factory method.
auto thread = app.CreateThread<ExampleRTThread>();
// Start the application, which starts all the registered threads (any thread
// passed to App::RegisterThread) in the order they are registered.
app.Start();
std::cout << "App started\n";
// This function blocks until SIGINT or SIGTERM are received.
cactus_rt::WaitForAndHandleTerminationSignal();
std::cout << "Caught signal, requesting stop...\n";
// We ask the application to stop, which stops all threads in the order they
// are created. If you want the application to run indefinitely, remove this
// line.
app.RequestStop();
// We wait until all threads registered are done here.
app.Join();
std::cout << "Done\n";
return 0;
}