RTUtility.cpp
Go to the documentation of this file.
1#include "RTUtility.h"
2
3#include <errno.h>
4
5#include <thread>
6
7#include <fcntl.h>
8#include <sched.h>
9#include <sys/stat.h>
10#include <sys/syscall.h>
11
13
15{
16 bool
18 {
19 long pid = syscall(SYS_gettid);
20 ARMARX_INFO << "Elevating priority of thread #" << pid << " to " << priority;
21 ARMARX_INFO << "Priority before: " << sched_getscheduler(static_cast<int>(pid));
22 struct sched_param param;
23 param.sched_priority = priority;
24 if (sched_setscheduler(static_cast<int>(pid), SCHED_FIFO | SCHED_RESET_ON_FORK, &param) ==
25 -1)
26 {
27 int error = errno;
28 ARMARX_WARNING << "sched_setscheduler failed: " << std::string(strerror(error));
29 return false;
30 }
31 if (sched_getparam(static_cast<int>(pid), &param) == -1)
32 {
33 int error = errno;
34 ARMARX_WARNING << "sched_getparam failed: " << std::string(strerror(error));
35 return false;
36 }
37 int new_priority = param.sched_priority;
38 if (new_priority == priority)
39 {
40 ARMARX_IMPORTANT << "Successfully elevated priority of thread #" << pid
41 << " to new priority " << new_priority;
42 }
43 else
44 {
45 ARMARX_ERROR << "Failed to elevate priority of thread #" << pid;
46 }
47
48 return true;
49 }
50
51 bool
52 RTUtility::pinThreadToCPU(unsigned int cpu)
53 {
54 long pid = syscall(SYS_gettid);
55 unsigned int availableCores = std::thread::hardware_concurrency();
56 if (availableCores < cpu)
57 {
58 ARMARX_ERROR << "Trying to pin thread #" << pid << " to CPU #" << cpu << ", but only "
59 << availableCores << " cores are available";
60 return false;
61 }
62
63 ARMARX_INFO << "Pinning thread #" << pid << " to CPU #" << cpu;
64 cpu_set_t mask;
65 CPU_ZERO(&mask);
66 CPU_SET(cpu, &mask);
67 int retval = sched_setaffinity(static_cast<int>(pid), sizeof(mask), &mask);
68 if (retval != 0)
69 {
70 ARMARX_ERROR << "Failed to pin thread #" << pid << " to CPU #" << cpu;
71 return false;
72 }
73 cpu_set_t mask2;
74 CPU_ZERO(&mask2);
75 CPU_SET(cpu, &mask2);
76 sched_getaffinity(static_cast<int>(pid), sizeof(mask2), &mask2);
77 bool matches = CPU_EQUAL(&mask, &mask2);
78 if (matches)
79 {
80 ARMARX_IMPORTANT << "Successfully pinned thread #" << pid << " to CPU #" << cpu;
81 return true;
82 }
83 else
84 {
85 ARMARX_ERROR << "Failed to pin thread #" << pid << " to CPU #" << cpu;
86 return false;
87 }
88 }
89
90 static int fd_low_latency_target = -1;
91 static constexpr std::int32_t LOW_LATENCY_MAX_RESPONSE_TIME = 0;
92
93 bool
95 {
96 ARMARX_INFO << "Starting low latency mode by writing " << LOW_LATENCY_MAX_RESPONSE_TIME
97 << " to /dev/cpu_dma_latency and keeping the file open";
98
99 struct stat s;
100 int err;
101 err = stat("/dev/cpu_dma_latency", &s);
102 if (err == -1)
103 {
104 ARMARX_WARNING << "stat /dev/cpu_dma_latency failed: " << strerror(errno);
105 return false;
106 }
107 fd_low_latency_target = open("/dev/cpu_dma_latency", O_RDWR);
108 if (fd_low_latency_target == -1)
109 {
110 ARMARX_WARNING << "open /dev/cpu_dma_latency failed: " << strerror(errno);
111 return false;
112 }
113
114 err = static_cast<int>(write(fd_low_latency_target,
115 &LOW_LATENCY_MAX_RESPONSE_TIME,
116 sizeof(LOW_LATENCY_MAX_RESPONSE_TIME)));
117 if (err < 1)
118 {
119 ARMARX_WARNING << "error writing " << LOW_LATENCY_MAX_RESPONSE_TIME
120 << " to /dev/cpu_dma_latency";
121 close(fd_low_latency_target);
122 return false;
123 }
124 ARMARX_IMPORTANT << "Successfully set /dev/cpu_dma_latency to "
125 << LOW_LATENCY_MAX_RESPONSE_TIME << " µs\n";
126 return true;
127 }
128
129 bool
131 {
132 ARMARX_INFO << "Stopping low latency mode by closing file /dev/cpu_dma_latency";
133 if (fd_low_latency_target >= 0)
134 {
135 close(fd_low_latency_target);
136 return true;
137 }
138 else
139 {
140 ARMARX_WARNING << "Low latency mode not active!";
141 return false;
142 }
143 }
144
145
146} // namespace armarx::control::ethercat
static bool pinThreadToCPU(unsigned int cpu)
Pins the calling thread to the CPU with the given id.
Definition RTUtility.cpp:52
static bool stopLowLatencyMode()
Deactivate low latency mode of the system.
static bool elevateThreadPriority(int priority)
Elevate the thread priority of the calling thread to the given priority.
Definition RTUtility.cpp:17
static bool startLowLatencyMode()
Activate low latency mode of the system.
Definition RTUtility.cpp:94
#define ARMARX_INFO
The normal logging level.
Definition Logging.h:181
#define ARMARX_IMPORTANT
The logging level for always important information, but expected behaviour (in contrast to ARMARX_WAR...
Definition Logging.h:190
#define ARMARX_ERROR
The logging level for unexpected behaviour, that must be fixed.
Definition Logging.h:196
#define ARMARX_WARNING
The logging level for unexpected behaviour, but not a serious problem.
Definition Logging.h:193