src/debug/real-time-logger.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2018,
3  * Joseph Mirabel
4  *
5  * LAAS-CNRS
6  *
7  */
8 
10 
11 #include <boost/date_time/posix_time/posix_time.hpp>
12 #include <boost/thread/thread.hpp>
13 
14 namespace dynamicgraph {
15 RealTimeLogger::RealTimeLogger(const std::size_t &bufferSize)
16  : buffer_(bufferSize, NULL),
17  frontIdx_(0),
18  backIdx_(0),
19  oss_(NULL),
20  nbDiscarded_(0) {
21  for (std::size_t i = 0; i < buffer_.size(); ++i) buffer_[i] = new Data;
22 }
23 
25  // Check that we are not spinning...
26  for (std::size_t i = 0; i < buffer_.size(); ++i) delete buffer_[i];
27 }
28 
30  if (empty()) return false;
32  frontIdx_ = (frontIdx_ + 1) % buffer_.size();
33  std::string str = data->buf.str();
34  // It is important to pass str.c_str() and not str
35  // because the str object may contains a '\0' so
36  // str.size() may be different from strlen(str.c_str())
37  for (std::size_t i = 0; i < outputs_.size(); ++i)
38  outputs_[i]->write(str.c_str());
39  return true;
40 }
41 
42 RTLoggerStream RealTimeLogger::front() {
43  // If no output or if buffer is full, discard message.
44  if (outputs_.empty() || full()) {
45  nbDiscarded_++;
46  return RTLoggerStream(NULL, oss_);
47  }
48  bool alone = wmutex.try_lock();
49  // If someone is writting, discard message.
50  if (!alone) {
51  nbDiscarded_++;
52  return RTLoggerStream(NULL, oss_);
53  }
55  // backIdx_ = (backIdx_+1) % buffer_.size();
56  // Reset position of cursor
57  data->buf.pubseekpos(0);
58  oss_.rdbuf(&data->buf);
59  return RTLoggerStream(this, oss_);
60 }
61 
67  boost::thread t_;
68 
69  explicit thread(RealTimeLogger *logger)
70  : requestShutdown_(false),
71  threadPolicy_(SCHED_OTHER),
72  threadPriority_(0),
73  changedThreadParams(true),
74  t_(&thread::spin, this, logger) {}
75 
76  // void setThreadPolicy(int policy) {
77  // threadPolicy_ = policy;
78  // changedThreadParams = true;
79  // }
80 
81  // void setPriority(int priority) {
82  // threadPriority_ = priority;
83  // changedThreadParams = true;
84  // }
85 
86  // int getThreadPolicy() { return threadPolicy_; }
87  // int getThreadPriority() { return threadPriority_; }
88 
90  int threadPolicy;
91  struct sched_param threadParam;
92  if (pthread_getschedparam(pthread_self(), &threadPolicy, &threadParam) ==
93  0) {
94  threadPolicy = threadPolicy_;
95  threadParam.sched_priority = threadPriority_;
96  if (threadParam.sched_priority < sched_get_priority_min(threadPolicy))
97  threadParam.sched_priority = sched_get_priority_min(threadPolicy);
98 
99  pthread_setschedparam(pthread_self(), threadPolicy, &threadParam);
100  changedThreadParams = false;
101  }
102  }
103 
104  void spin(RealTimeLogger *logger) {
105  // Change the thread's scheduler from real-time to normal
106  // and reduce its priority
107 
108  while (!requestShutdown_ || !logger->empty()) {
109  // If the logger did not write anything, it means the buffer is empty.
110  // Do a pause
111  if (!logger->spinOnce())
112  boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
113  if (changedThreadParams) changeThreadParams();
114  }
115  }
116 };
117 
120 
122  if (instance_ == NULL) {
123  instance_ = new RealTimeLogger(1000);
124  thread_ = new thread(instance_);
125  }
126  return *instance_;
127 }
128 
130  if (instance_ == NULL) return;
131  thread_->requestShutdown_ = true;
132  thread_->t_.join();
133  delete instance_;
134  delete thread_;
135 }
136 } // namespace dynamicgraph
std::size_t frontIdx_
Index of the next value to be read.
std::vector< LoggerStreamPtr_t > outputs_
data
Definition: setup.in.py:48
Main class of the real-time logger.
boost::mutex wmutex
The writer mutex.
static RealTimeLogger * instance_
RealTimeLogger(const std::size_t &bufferSize)


dynamic-graph
Author(s): Nicolas Mansard, Olivier Stasse
autogenerated on Sun Jun 25 2023 02:06:03