RTC Toolkit  2.0.0
readerHelpers.hpp
Go to the documentation of this file.
1 
12 #ifndef RTCTK_DATATASK_READERHELPERS_HPP
13 #define RTCTK_DATATASK_READERHELPERS_HPP
15 
16 #include <chrono>
17 #include <system_error>
18 #include <cmath>
19 
20 namespace rtctk::dataTask {
25 namespace detail {
26 
27 
37 inline std::chrono::milliseconds CalcTimeout(size_t count, float loop_frequency, float error_margin)
38 {
39  using namespace std::chrono;
40  return milliseconds{static_cast<int>(ceil(1000.0 * count / loop_frequency) * error_margin)};
41 }
42 
56 template <typename ReaderType, typename Operation>
57 std::error_code Read(ReaderType& reader, Operation&& op, size_t count, float loop_frequency, \
58  float error_margin)
59 {
61  using namespace std::chrono;
62 
63  auto timeout_short = CalcTimeout(1, loop_frequency, error_margin);
64  auto timeout_total = CalcTimeout(count, loop_frequency, error_margin);
65 
66  size_t read = 0;
67  std::error_code const ok;
68  std::pair<std::error_code, size_t> ret;
69  milliseconds time_elapsed {0};
70  auto time_start = system_clock::now();
71 
72  while (1) {
73  ret = reader.Read(std::forward<Operation>(op), count, timeout_short);
74  if(ret.first != ok) {
75  LOG4CPLUS_ERROR(GetLogger(), "!Reading from shm timed out: check if queue is being filled");
76  LOG4CPLUS_ERROR(GetLogger(), "Read: " << ret.second << " in " << timeout_short.count() << " ms");
77  LOG4CPLUS_ERROR(GetLogger(), "Expected: " << count);
78  return ret.first;
79  }
80  read += ret.second;
81  if (read == count) {
82  return {};
83  }
84 
85  time_elapsed = duration_cast<milliseconds>(system_clock::now() - time_start);
86  if (time_elapsed > timeout_total) {
87  LOG4CPLUS_ERROR(GetLogger(), "Reading from shm timed out: check if queue is being filled");
88  LOG4CPLUS_ERROR(GetLogger(), "Read: " << read << " in " << time_elapsed.count() << " ms");
89  LOG4CPLUS_ERROR(GetLogger(), "Expected: " << read);
90  return std::make_error_code(std::errc::timed_out);
91  }
92  }
93 }
94 
95 
96 
108 template <typename ReaderType>
109 std::error_code Skip(ReaderType& reader, size_t count, float loop_frequency, \
110  float error_margin)
111 {
113  using namespace std::chrono;
114 
115  auto timeout_short = CalcTimeout(1, loop_frequency, error_margin);
116  auto timeout_total = CalcTimeout(count, loop_frequency, error_margin);
117 
118  size_t skipped = 0;
119  std::error_code const ok;
120  std::pair<std::error_code, size_t> ret;
121  milliseconds time_elapsed {0};
122  auto time_start = system_clock::now();
123 
124  while (1) {
125  ret = reader.Skip(count, timeout_short);
126  if(ret.first != ok) {
127  LOG4CPLUS_ERROR(GetLogger(), "!Skipping from shm timed out: check if queue is being filled");
128  LOG4CPLUS_ERROR(GetLogger(), "Read: " << ret.second << " in " << timeout_short.count() << " ms");
129  LOG4CPLUS_ERROR(GetLogger(), "Expected: " << count);
130  return ret.first;
131  }
132  skipped += ret.second;
133  if (skipped == count) {
134  return {};
135  }
136 
137  time_elapsed = duration_cast<milliseconds>(system_clock::now() - time_start);
138  if (time_elapsed > timeout_total) {
139  LOG4CPLUS_ERROR(GetLogger(), "Skipping from shm timed out: check if queue is being filled");
140  LOG4CPLUS_ERROR(GetLogger(), "Read: " << skipped << " in " << time_elapsed.count() << " ms");
141  LOG4CPLUS_ERROR(GetLogger(), "Expected: " << skipped);
142  return std::make_error_code(std::errc::timed_out);
143  }
144  }
145 }
146 
147 
156 template <typename ReaderType>
157 std::error_code Reset(ReaderType& reader)
158 {
159  if (reader.Size() != 0) {
160  return reader.Reset();
161  }
162  return {};
163 }
164 
173 template <typename ReaderType>
174 size_t NumFree(ReaderType& reader)
175 {
176  return reader.Size() - reader.NumAvailable();
177 }
178 
179 } // namespace
180 
181 } // namespace
182 
183 #endif
rtctk::dataTask::detail::Reset
std::error_code Reset(ReaderType &reader)
helper function to reset the ipcq.reader to latest sample
Definition: readerHelpers.hpp:157
rtctk::dataTask::detail::CalcTimeout
std::chrono::milliseconds CalcTimeout(size_t count, float loop_frequency, float error_margin)
free helper function to calulate the estimated time to read the a number of samples at a given freque...
Definition: readerHelpers.hpp:37
rtctk::componentFramework::GetLogger
log4cplus::Logger & GetLogger(const std::string &name="")
Get handle to a specific logger (used with logging macros)
rtctk::dataTask::detail::Read
std::error_code Read(ReaderType &reader, Operation &&op, size_t count, float loop_frequency, float error_margin)
helper function to wrap the ipcq.read with handling of timeouts and count values
Definition: readerHelpers.hpp:57
rtctk::dataTask::detail::NumFree
size_t NumFree(ReaderType &reader)
helper function to get the free space in the shm.
Definition: readerHelpers.hpp:174
rtctk::dataTask
Definition: messageQueue.hpp:20
rtctk::dataTask::detail::Skip
std::error_code Skip(ReaderType &reader, size_t count, float loop_frequency, float error_margin)
helper function to wrap the ipcq.skip with handling of timeouts and count values
Definition: readerHelpers.hpp:109
rtctk::telRepub::make_error_code
std::error_code make_error_code(MudpiProcessingError e)
Create std::error_code from ProcessingError.
Definition: mudpiProcessingError.hpp:113
logger.hpp
Logging Support Library based on log4cplus.
rtctk_config_tool.read
def read(repo, path, output)
Definition: rtctk_config_tool.py:188