GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/traces/tracer-real-time.cpp Lines: 125 152 82.2 %
Date: 2023-03-15 12:04:10 Branches: 116 254 45.7 %

Line Branch Exec Source
1
/*
2
 * Copyright 2010,
3
 * François Bleibel,
4
 * Olivier Stasse,
5
 *
6
 * CNRS/AIST
7
 *
8
 */
9
10
/* --------------------------------------------------------------------- */
11
/* --- INCLUDE --------------------------------------------------------- */
12
/* --------------------------------------------------------------------- */
13
14
/* DG */
15
#include <dynamic-graph/all-commands.h>
16
#include <dynamic-graph/debug.h>
17
#include <dynamic-graph/factory.h>
18
#include <dynamic-graph/pool.h>
19
#include <dynamic-graph/tracer-real-time.h>
20
21
#include <boost/bind.hpp>
22
#include <iomanip>
23
24
using namespace std;
25
using namespace dynamicgraph;
26
27
1
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(TracerRealTime, "TracerRealTime");
28
29
/* --------------------------------------------------------------------- */
30
/* --- DGOUTSTRINGSTREAM ---------------------------------------------- */
31
/* --------------------------------------------------------------------- */
32
33
2
OutStringStream::OutStringStream()
34
2
    : std::ostringstream(), buffer(0), index(0), bufferSize(0), full(false) {
35
  dgDEBUGINOUT(15);
36
}
37
38
OutStringStream::~OutStringStream() {
39
  dgDEBUGIN(15);
40
  delete[] buffer;
41
  dgDEBUGOUT(15);
42
}
43
44
1
void OutStringStream::resize(const std::streamsize &size) {
45
  dgDEBUGIN(15);
46
47
1
  index = 0;
48
1
  bufferSize = size;
49
1
  full = false;
50
51
1
  delete[] buffer;
52
1
  buffer = new char[static_cast<size_t>(size)];
53
54
  dgDEBUGOUT(15);
55
1
}
56
57
1000
bool OutStringStream::addData(const char *data, const std::streamoff &size) {
58
  dgDEBUGIN(15);
59
1000
  std::streamsize towrite = static_cast<std::streamsize>(size);
60
1000
  if (index + towrite > bufferSize) {
61
    dgDEBUGOUT(15);
62
    full = true;
63
    return false;
64
  }
65
1000
  memcpy(buffer + index, data, static_cast<size_t>(towrite));
66
1000
  index += towrite;
67
  dgDEBUGOUT(15);
68
1000
  return true;
69
}
70
71
1
void OutStringStream::dump(std::ostream &os) {
72
  dgDEBUGIN(15);
73
1
  os.write(buffer, index);
74
  dgDEBUGOUT(15);
75
1
}
76
77
2
void OutStringStream::empty() {
78
  dgDEBUGIN(15);
79
2
  index = 0;
80
2
  full = false;
81
  dgDEBUGOUT(15);
82
2
}
83
84
/* --------------------------------------------------------------------- */
85
/* --------------------------------------------------------------------- */
86
/* --------------------------------------------------------------------- */
87
88
1
TracerRealTime::TracerRealTime(const std::string &n)
89
1
    : Tracer(n), bufferSize(BUFFER_SIZE_DEFAULT) {
90
  dgDEBUGINOUT(15);
91
92
  /* --- Commands --- */
93
  {
94
    using namespace dynamicgraph::command;
95
    std::string doc = docCommandVoid0(
96

2
        "Trash the current content of the buffers, without saving it.");
97

1
    addCommand("empty",
98
1
               makeCommandVoid0(*this, &TracerRealTime::emptyBuffers, doc));
99
100

1
    addCommand("getBufferSize",
101
1
               makeDirectGetter(*this, &bufferSize,
102

2
                                docDirectGetter("bufferSize", "int")));
103

1
    addCommand("setBufferSize",
104
1
               makeDirectSetter(*this, &bufferSize,
105

2
                                docDirectSetter("bufferSize", "int")));
106
  }  // using namespace command
107
108
  dgDEBUGOUT(15);
109
1
}
110
111
/* --------------------------------------------------------------------- */
112
/* --------------------------------------------------------------------- */
113
/* --------------------------------------------------------------------- */
114
115
2
void TracerRealTime::openFile(const SignalBase<int> &sig,
116
                              const std::string &givenname) {
117
  dgDEBUGIN(15);
118
4
  string signame;
119
2
  if (givenname.length()) {
120
2
    signame = givenname;
121
  } else {
122
    signame = sig.shortName();
123
  }
124
125

6
  string filename = rootdir + basename + signame + suffix;
126
  dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
127

2
  std::ofstream *newfile = new std::ofstream(filename.c_str());
128

2
  if (!newfile->good()) {
129
1
    delete newfile;
130
    DG_THROW ExceptionTraces(
131
        ExceptionTraces::NOT_OPEN,
132


1
        "Could not open file " + filename + " for signal " + signame, "");
133
  }
134
  dgDEBUG(5) << "Newfile:" << (void *)newfile << endl;
135
1
  hardFiles.push_back(newfile);
136
  dgDEBUG(5) << "Creating Outstringstream" << endl;
137
138
  // std::stringstream * newbuffer = new std::stringstream ();
139

1
  OutStringStream *newbuffer = new OutStringStream();  // std::stringstream ();
140
1
  newbuffer->resize(bufferSize);
141
1
  newbuffer->givenname = givenname;
142
1
  files.push_back(newbuffer);
143
144
  dgDEBUGOUT(15);
145
1
}
146
147
2
void TracerRealTime::closeFiles() {
148
  dgDEBUGIN(15);
149
4
  std::lock_guard<std::mutex> files_lock(files_mtx);
150
151
2
  FileList::iterator iter = files.begin();
152
2
  HardFileList::iterator hardIter = hardFiles.begin();
153
154
3
  while (files.end() != iter) {
155
    dgDEBUG(25) << "Close the files." << endl;
156
157
1
    std::stringstream *file = dynamic_cast<stringstream *>(*iter);
158
1
    std::ofstream *hardFile = *hardIter;
159
160
1
    (*hardFile) << flush;
161
1
    hardFile->close();
162
1
    delete file;
163
1
    delete hardFile;
164
165
1
    ++iter;
166
1
    ++hardIter;
167
  }
168
169
  dgDEBUG(25) << "Clear the lists." << endl;
170
2
  files.clear();
171
2
  hardFiles.clear();
172
173
  dgDEBUGOUT(15);
174
2
}
175
176
1
void TracerRealTime::trace() {
177
  dgDEBUGIN(15);
178
179
1
  FileList::iterator iter = files.begin();
180
1
  HardFileList::iterator hardIter = hardFiles.begin();
181
182
2
  while (files.end() != iter) {
183
    dgDEBUG(35) << "Next" << endl;
184
1
    std::ostream *os = *iter;
185
1
    if (NULL == os) {
186
      DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN, "The buffer is null",
187
                               "");
188
    }
189
    // std::stringstream & file = * dynamic_cast< stringstream* >(os);
190
1
    OutStringStream *file = dynamic_cast<OutStringStream *>(os);  // segfault
191
1
    if (NULL == file) {
192
      DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
193
                               "The buffer is not open", "");
194
    }
195
196
1
    std::ofstream &hardFile = **hardIter;
197

1
    if (!hardFile.good()) {
198
      DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
199
                               "The file is not open", "");
200
    }
201
202


1
    if ((hardFile.good()) && (NULL != file)) {
203
1
      file->dump(hardFile);
204
1
      file->empty();
205
1
      hardFile.flush();
206
    }
207
208
1
    ++iter;
209
1
    ++hardIter;
210
  }
211
212
  dgDEBUGOUT(15);
213
1
}
214
215
2
void TracerRealTime::emptyBuffers() {
216
  dgDEBUGIN(15);
217
3
  for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
218
    // std::stringstream & file = * dynamic_cast< stringstream* >(*iter);
219
    try {
220
1
      OutStringStream &file = *dynamic_cast<OutStringStream *>(*iter);
221
1
      file.empty();
222
      // file.str("");
223
    } catch (...) {
224
      DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
225
                               "The buffer is not open", "");
226
    }
227
  }
228
  dgDEBUGOUT(15);
229
2
}
230
231
1000
void TracerRealTime::recordSignal(std::ostream &os,
232
                                  const SignalBase<int> &sig) {
233
  dgDEBUGIN(15);
234
235
  try {
236
1000
    OutStringStream &file = dynamic_cast<OutStringStream &>(os);
237

1000
    file.str("");
238
    dgDEBUG(45) << "Empty file [" << file.tellp() << "] <" << file.str().c_str()
239
                << "> " << endl;
240
241
1000
    Tracer::recordSignal(file, sig);
242

1000
    file.addData(file.str().c_str(), file.tellp());
243
    dgDEBUG(35) << "Write data [" << file.tellp() << "] <" << file.str().c_str()
244
                << "> " << endl;
245
246
  } catch (ExceptionAbstract &exc) {
247
    throw;
248
  } catch (...) {
249
    DG_THROW ExceptionTraces(ExceptionTraces::NOT_OPEN,
250
                             "The buffer is not open", "");
251
  }
252
253
  dgDEBUGOUT(15);
254
1000
  return;
255
}
256
257
/* --------------------------------------------------------------------- */
258
/* --------------------------------------------------------------------- */
259
/* --------------------------------------------------------------------- */
260
261
1
void TracerRealTime::display(std::ostream &os) const {
262
2
  os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause")
263




1
     << "] : " << endl
264

1
     << "  - Dep list: " << endl;
265
266
1
  FileList::const_iterator iterFile = files.begin();
267
2
  for (SignalList::const_iterator iter = toTraceSignals.begin();
268
3
       toTraceSignals.end() != iter; ++iter) {
269
    dgDEBUG(35) << "Next" << endl;
270
1
    const OutStringStream *file = dynamic_cast<OutStringStream *>(*iterFile);
271

1
    os << "     -> " << (*iter)->getName();
272


1
    if (file->givenname.length()) os << " (in " << file->givenname << ")";
273
1
    os << "\t";
274
1
    if (file) {
275
1
      const std::streamsize PRECISION = os.precision();
276
1
      const std::streamsize SIZE = file->index;
277
1
      const std::streamsize MSIZE = file->bufferSize;
278
1
      unsigned int dec = 0;
279
2
      std::string unit = "";
280

1
      if ((SIZE >> 30) || (MSIZE >> 30)) {
281
        dec = 30;
282
        unit = "Go";
283

1
      } else if ((SIZE >> 20) || (MSIZE >> 20)) {
284
        dec = 20;
285
        unit = "Mo";
286

1
      } else if ((SIZE >> 10) || (MSIZE >> 10)) {
287
1
        dec = 10;
288
1
        unit = "Ko";
289
      }
290

1
      os << "[" << std::setw(1) << std::setprecision(1)
291
1
         << (((double)SIZE + 0.0) / (1 << dec)) << unit << "/"
292


1
         << std::setprecision(2) << (((double)MSIZE + 0.0) / (1 << dec)) << unit
293

1
         << "]\t";
294

1
      if (file->full) os << "(FULL)";
295
1
      os.precision(PRECISION);
296
    }
297
1
    os << endl;
298
1
    ++iterFile;
299
  }
300
1
}
301
302
std::ostream &operator<<(std::ostream &os, const TracerRealTime &t) {
303
  t.display(os);
304
  return os;
305
}