12#include "SampleAppsHelper.h"
17using namespace RSI::RapidCode::RealTimeTasks;
20constexpr bool LOOP_FOREVER =
false;
21constexpr int64_t LOOP_PERIOD_MS = 1000;
23constexpr bool PRINT_DETAILED_INFO =
true;
24constexpr bool PRINT_TIMING_METRICS =
true;
26constexpr int32_t SEPARATOR_LENGTH = 80;
29std::atomic<bool> stopRequested(
false);
30void SignalHandler(
int signal)
34 stopRequested.store(
true);
39template<
typename T,
typename U = std::shared_ptr<T>>
40std::vector<U> ConvertToSTLVector(
const RapidVector<T*>& src) {
42 dst.reserve(src.Size());
43 for (
auto* p : src) dst.emplace_back(p);
47std::vector<std::string> ConvertToSTLVector(
const RapidVector<const char*>& src) {
48 std::vector<std::string> dst;
49 dst.reserve(src.Size());
50 for (
const char* p : src) {
51 dst.emplace_back(std::string(p));
61 case RTTaskState::Dead:
return "Dead";
62 case RTTaskState::Disabled:
return "Disabled";
63 case RTTaskState::Waiting:
return "Waiting";
64 case RTTaskState::Running:
return "Running";
65 default:
return "Unknown State";
73 case RTTaskManagerState::Dead:
return "Dead";
74 case RTTaskManagerState::Running:
return "Running";
75 case RTTaskManagerState::Stopped:
return "Stopped";
76 default:
return "Unknown State";
84 case PlatformType::Native:
return "Native";
85 case PlatformType::INtime:
return "INtime";
86 case PlatformType::Linux:
return "Linux";
87 case PlatformType::Windows:
return "Windows";
88 default:
return "Unknown Platform";
92std::string FormatUserLabel(std::string_view userLabel, std::string_view autoGenerated =
"")
94 if (userLabel.empty() || (!autoGenerated.empty() && userLabel == autoGenerated))
96 return std::string(userLabel) +
" ";
99void AppendTaskSummary(std::ostream& os,
const std::shared_ptr<RTTask>& task)
106 std::string userLabel = FormatUserLabel(taskParams.UserLabel);
107 std::string executionCount =
109 "N/A" : std::to_string(taskStatus.ExecutionCount);
111 os <<
" Task " << userLabel
112 <<
"(ID: " << task->IdGet() <<
")"
113 <<
" - State: " << ToString(taskStatus.State)
114 <<
" [Execution Count: " << executionCount <<
"]\n";
117 if (PRINT_DETAILED_INFO)
119 os <<
" Function: " << taskParams.FunctionName <<
"\n";
121 if (taskParams.LibraryName !=
nullptr && taskParams.LibraryName[0] !=
'\0')
123 os <<
" Library: " << taskParams.LibraryName <<
"\n";
126 if (taskParams.LibraryDirectory !=
nullptr && taskParams.LibraryDirectory[0] !=
'\0')
128 os <<
" Library Directory: " << taskParams.LibraryDirectory <<
"\n";
131 os <<
" Priority: " <<
static_cast<int32_t
>(taskParams.Priority) <<
"\n";
134 os <<
" Repeats: " << repeatsOrForever(taskParams.Repeats) <<
"\n";
135 os <<
" Period: " << taskParams.Period <<
" samples\n";
136 os <<
" Phase: " << taskParams.Phase <<
" samples\n";
140 if (PRINT_TIMING_METRICS)
142 if (taskParams.EnableTiming)
145 os <<
" Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeLast) <<
" ns\n";
146 os <<
" Max Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMax) <<
" ns\n";
147 os <<
" Min Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMin) <<
" ns\n";
148 os <<
" Mean Execution Time: " << timeOrInvalid(taskStatus.ExecutionTimeMean) <<
" ns\n";
152 os <<
" Timing: Disabled\n";
157void AppendTaskManagerSummary(std::ostream& os,
const std::shared_ptr<RTTaskManager>& taskManager)
163 os << std::string(SEPARATOR_LENGTH,
'-') <<
"\n";
166 std::string autoGeneratedLabel =
"TaskManager_" + std::to_string(taskManager->IdGet());
167 std::string managerLabel = FormatUserLabel(taskManagerParams.UserLabel, autoGeneratedLabel);
169 os <<
"Task Manager " << managerLabel
170 <<
"(ID: " << taskManager->IdGet() <<
")"
171 <<
" - State: " << ToString(taskManagerStatus.State)
172 <<
" [Cycle Count: " << taskManagerStatus.CycleCount <<
"]\n";
175 if (PRINT_DETAILED_INFO)
177 os <<
"Platform: " << ToString(taskManagerParams.Platform);
178 if (taskManagerParams.Platform == PlatformType::INtime)
180 os <<
" - " << taskManagerParams.NodeName;
182 else if (taskManagerParams.Platform == PlatformType::Linux || taskManagerParams.Platform == PlatformType::Windows)
184 if (taskManagerParams.CpuCore != -1)
186 os <<
" - CPU Core: " << taskManagerParams.CpuCore;
191 if (taskManagerParams.RTTaskDirectory !=
nullptr && taskManagerParams.RTTaskDirectory[0] !=
'\0')
193 os <<
"RTTask Directory: " << taskManagerParams.RTTaskDirectory <<
"\n";
198 if (PRINT_TIMING_METRICS)
200 os <<
"Cycle Time Mean: " << taskManagerStatus.CycleTimeMean <<
" ns\n";
201 os <<
"Cycle Time Last: " << taskManagerStatus.CycleTimeLast <<
" ns\n";
202 os <<
"Cycle Time Max: " << taskManagerStatus.CycleTimeMax <<
" ns\n";
203 os <<
"Cycle Time Min: " << taskManagerStatus.CycleTimeMin <<
" ns\n";
207 std::vector<std::shared_ptr<RTTask>> tasks = ConvertToSTLVector(taskManager->TasksGet());
210 if (taskManagerStatus.TaskSubmissionCount != 0)
212 os <<
"\nTasks submitted: " << taskManagerStatus.TaskSubmissionCount;
213 if (tasks.size() != 0)
215 os <<
", Current tasks: " << tasks.size();
221 for (
const auto& task : tasks)
223 AppendTaskSummary(os, task);
227void AppendGlobalTagSummary(std::ostream& os,
const std::shared_ptr<RTTaskManager>& taskManager)
229 std::vector<std::string> globalTagNames = ConvertToSTLVector(taskManager->GlobalNamesGet());
231 os <<
"Global Tags Count: " << globalTagNames.size() <<
"\n";
232 for (
const auto& tagName : globalTagNames)
235 os <<
" " << tagName <<
": " << tag.
UInt64 <<
"\n";
242 const std::string SAMPLE_APP_NAME =
"Utilities: Print Real-Time Tasks Summary";
246 std::signal(SIGINT, SignalHandler);
253 std::ostringstream rtTasksSummary;
254 auto nextWakeupTime = std::chrono::steady_clock::now();
255 while (!stopRequested.load())
257 rtTasksSummary.str(
""); rtTasksSummary.clear();
258 rtTasksSummary << std::string(SEPARATOR_LENGTH,
'-') <<
"\n";
262 rtTasksSummary <<
"Discovered " << taskManagers.size() <<
" task managers:\n";
264 if (taskManagers.size() != 0)
267 for (
const auto& taskManager : taskManagers)
269 AppendTaskManagerSummary(rtTasksSummary, taskManager);
271 rtTasksSummary << std::string(SEPARATOR_LENGTH,
'-') <<
"\n";
279 std::cout << rtTasksSummary.str() << std::endl;
281 if (!LOOP_FOREVER)
break;
283 nextWakeupTime += std::chrono::milliseconds(LOOP_PERIOD_MS);
284 std::this_thread::sleep_until(nextWakeupTime);
289 catch (
const std::exception &ex)
291 std::cerr << ex.what() << std::endl;
static RapidVector< RTTaskManager * > Discover()
Discover all active RTTaskManager instances.
RTTaskManagerState
Enum representing the possible states of an RTTaskManager.
RTTaskState
Enum representing the possible states of a real-time task.
PlatformType
Enum representing the platform type for an RTTaskManager.
static void PrintFooter(std::string sampleAppName, int exitCode)
Print a message to indicate the sample app has finished and if it was successful or not.
static void PrintHeader(std::string sampleAppName)
Print a start message to indicate that the sample app has started.
RTTaskCreationParameters specifies all the information required to create and configure a real-time t...
static constexpr int32_t RepeatForever
Special value to indicate the task should repeat forever.
RTTaskInfo provides information about a real-time task, including its creation parameters....
RTTaskManagerCreationParameters specifies all the information required to create and configure an RTT...
Information about RTTaskManager firmware, including its creation parameters and ID....
RTTaskManagerStatus provides status information for RTTaskManager firmware, including its current sta...
RTTaskStatus provides status information for a real-time task, including its current state,...
static constexpr uint64_t InvalidExecutionTime
Invalid value for execution time, indicating timing is not enabled or the task has not executed.
static constexpr int64_t InvalidExecutionCount
Invalid value for execution count, indicating the task has not executed.
Union representing a generic RMP firmware value with multiple data types, stored in 64-bits.
uint64_t UInt64
64-bit unsigned integer.