Flexiv RDK APIs  1.6.0
test_scheduler.cpp
1 
9 #include <flexiv/rdk/utility.hpp>
10 #include <spdlog/spdlog.h>
11 
12 #include <iostream>
13 #include <thread>
14 #include <chrono>
15 #include <mutex>
16 #include <atomic>
17 
18 namespace {
20 struct SharedData
21 {
22  int64_t measured_interval = 0;
23 } g_data;
24 
26 std::mutex g_mutex;
27 
29 std::atomic<bool> g_stop_sched = {false};
30 }
31 
33 void highPriorityTask()
34 {
35  static unsigned int loop_counter = 0;
36 
37  // Scheduler loop interval start time point
38  static std::chrono::high_resolution_clock::time_point tic;
39 
40  try {
41  // Mark loop interval end point
42  auto toc = std::chrono::high_resolution_clock::now();
43 
44  // Calculate scheduler's interrupt interval and print
45  auto measured_interval
46  = std::chrono::duration_cast<std::chrono::microseconds>(toc - tic).count();
47 
48  // Safely write shared data
49  {
50  std::lock_guard<std::mutex> lock(g_mutex);
51  g_data.measured_interval = measured_interval;
52  }
53 
54  // Stop scheduler after 5 seconds
55  if (++loop_counter > 5000) {
56  loop_counter = 0;
57  g_stop_sched = true;
58  }
59 
60  // Mark loop interval start point
61  tic = std::chrono::high_resolution_clock::now();
62 
63  } catch (const std::exception& e) {
64  spdlog::error(e.what());
65  g_stop_sched = true;
66  }
67 }
68 
70 void lowPriorityTask()
71 {
72  static uint64_t accumulated_time = 0;
73  static uint64_t num_measures = 0;
74  static float avg_interval = 0.0;
75  int measured_interval = 0;
76 
77  // Safely read shared data
78  {
79  std::lock_guard<std::mutex> lock(g_mutex);
80  measured_interval = g_data.measured_interval;
81  }
82 
83  // calculate average time interval
84  accumulated_time += measured_interval;
85  num_measures++;
86  avg_interval = (float)accumulated_time / (float)num_measures;
87 
88  // print time interval of high-priority periodic task
89  spdlog::info(
90  "High-priority task interval (curr | avg) = {} | {} us", measured_interval, avg_interval);
91 }
92 
93 void PrintHelp()
94 {
95  // clang-format off
96  std::cout << "Required arguments: None" << std::endl;
97  std::cout << "Optional arguments: None" << std::endl;
98  std::cout << std::endl;
99  // clang-format on
100 }
101 
102 int main(int argc, char* argv[])
103 {
104  // Parse Parameters
105  //==============================================================================================
106  if (flexiv::rdk::utility::ProgramArgsExistAny(argc, argv, {"-h", "--help"})) {
107  PrintHelp();
108  return 1;
109  }
110 
111  try {
112  // Periodic Tasks
113  //==========================================================================================
114  flexiv::rdk::Scheduler scheduler;
115  // Add periodic task with 1ms interval and highest applicable priority
116  scheduler.AddTask(std::bind(highPriorityTask), "HP periodic", 1, scheduler.max_priority());
117  // Add periodic task with 1s interval and lowest applicable priority
118  scheduler.AddTask(std::bind(lowPriorityTask), "LP periodic", 1000, 0);
119  // Start all added tasks
120  scheduler.Start();
121 
122  // Block and wait for signal to stop scheduler tasks
123  while (!g_stop_sched) {
124  std::this_thread::sleep_for(std::chrono::milliseconds(1));
125  }
126  // Received signal to stop scheduler tasks
127  scheduler.Stop();
128 
129  // Restart scheduler after 2 seconds
130  spdlog::warn("Scheduler will restart in 2 seconds");
131  std::this_thread::sleep_for(std::chrono::seconds(2));
132  g_stop_sched = false;
133  scheduler.Start();
134 
135  // Wait for signal to stop scheduler tasks
136  while (!g_stop_sched) {
137  std::this_thread::sleep_for(std::chrono::milliseconds(1));
138  }
139  // Received signal to stop scheduler tasks, flexiv::rdk::Scheduler's destructor can also do
140  // the thread exit and resources cleanup
141 
142  } catch (const std::exception& e) {
143  spdlog::error(e.what());
144  return 1;
145  }
146 
147  return 0;
148 }
Real-time scheduler that can simultaneously run multiple periodic tasks. Parameters for each task are...
Definition: scheduler.hpp:22
int max_priority() const
[Non-blocking] Get maximum available priority for user tasks.
void AddTask(std::function< void(void)> &&callback, const std::string &task_name, int interval, int priority, int cpu_affinity=-1)
[Non-blocking] Add a new periodic task to the scheduler's task pool. Each task in the pool is assigne...
void Stop()
[Blocking] Stop all added tasks. The periodic execution will stop and all task threads will be closed...
void Start()
[Blocking] Start all added tasks. A dedicated thread will be created for each added task and the peri...