tracer.cpp
Go to the documentation of this file.
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 */
16 #include <dynamic-graph/debug.h>
17 #include <dynamic-graph/factory.h>
18 #include <dynamic-graph/pool.h>
19 #include <dynamic-graph/tracer.h>
20 #include <dynamic-graph/value.h>
21 
22 #include <boost/bind.hpp>
23 
24 using namespace std;
25 using namespace dynamicgraph;
26 using namespace dynamicgraph::command;
27 
29 
30 /* --------------------------------------------------------------------- */
31 /* --- CLASS ----------------------------------------------------------- */
32 /* --------------------------------------------------------------------- */
33 
34 Tracer::Tracer(const std::string n)
35  : Entity(n),
36  toTraceSignals(),
37  traceStyle(TRACE_STYLE_DEFAULT),
38  frequency(1),
39  basename(),
40  suffix(".dat"),
41  rootdir(),
42  namesSet(false),
43  files(),
44  names(),
45  play(false),
46  timeStart(0),
47  triger(boost::bind(&Tracer::recordTrigger, this, _1, _2), sotNOSIGNAL,
48  "Tracer(" + n + ")::triger") {
50 
51  /* --- Commands --- */
52  {
53  using namespace dynamicgraph::command;
54  std::string doc;
55 
56  doc = docCommandVoid2("Add a new signal to trace.", "string (signal name)",
57  "string (filename, empty for default");
58  addCommand("add",
60 
61  doc =
62  docCommandVoid0("Remove all signals. If necessary, close open files.");
63  addCommand("clear",
65 
66  doc = docCommandVoid3(
67  "Gives the args for file opening, and "
68  "if signals have been set, open the corresponding files.",
69  "string (dirname)", "string (prefix)", "string (suffix)");
70  addCommand("open", makeCommandVoid3(*this, &Tracer::openFiles, doc));
71 
72  doc = docCommandVoid0("Close all the open files.");
73  addCommand("close", makeCommandVoid0(*this, &Tracer::closeFiles, doc));
74 
75  doc = docCommandVoid0(
76  "If necessary, dump "
77  "(can be done automatically for some traces type).");
78  addCommand("dump", makeCommandVoid0(*this, &Tracer::trace, doc));
79 
80  doc = docCommandVoid0("Start the tracing process.");
81  addCommand("start", makeCommandVoid0(*this, &Tracer::start, doc));
82 
83  doc = docCommandVoid0("Stop temporarily the tracing process.");
84  addCommand("stop", makeCommandVoid0(*this, &Tracer::stop, doc));
85 
86  addCommand("getTimeStart",
88  docDirectGetter("timeStart", "int")));
89  addCommand("setTimeStart",
91  docDirectSetter("timeStart", "int")));
92  } // using namespace command
93 }
94 
95 /* --------------------------------------------------------------------- */
96 /* --------------------------------------------------------------------- */
97 /* --------------------------------------------------------------------- */
98 
100  const string &filename) {
101  dgDEBUGIN(15);
102  // openFile may throw so it should be called first.
103  if (namesSet) openFile(sig, filename);
104  toTraceSignals.push_back(&sig);
105  dgDEBUGF(15, "%p", &sig);
106  names.push_back(filename);
107  triger.addDependency(sig);
108  dgDEBUGOUT(15);
109 }
110 
111 void Tracer::addSignalToTraceByName(const string &signame,
112  const string &filename) {
113  dgDEBUGIN(15);
114  istringstream iss(signame);
116  addSignalToTrace(sig, filename);
117  dgDEBUGOUT(15);
118 }
119 
125  closeFiles();
126  toTraceSignals.clear();
128 }
129 
130 // void Tracer::
131 // parasite( SignalBase<int>& sig )
132 // {
133 // triger.parasite(sig);
134 // }
135 
136 void Tracer::openFiles(const std::string &rootdir_,
137  const std::string &basename_,
138  const std::string &suffix_) {
139  dgDEBUGIN(15);
140  std::basic_string<char>::size_type n = rootdir_.length();
141  rootdir = rootdir_;
142  if ((0 < n) & ('/' != rootdir[n - 1])) rootdir += '/';
143 
144  basename = basename_;
145  suffix = suffix_;
146 
147  if (files.size()) closeFiles();
148 
149  SignalList::const_iterator iter = toTraceSignals.begin();
150  NameList::const_iterator iterName = names.begin();
151  while (toTraceSignals.end() != iter) {
152  dgDEBUG(15) << "Open <" << (*iter)->getName() << "> in <" << *iterName
153  << ">." << std::endl;
154  openFile(**iter, *iterName);
155  ++iter;
156  ++iterName;
157  }
158 
159  namesSet = true;
160  dgDEBUGOUT(15);
161 }
162 
163 void Tracer::openFile(const SignalBase<int> &sig, const string &givenname) {
164  dgDEBUGIN(15);
165  string signame;
166  if (givenname.length()) {
167  signame = givenname;
168  } else {
169  signame = sig.shortName();
170  }
171 
172  string filename = rootdir + basename + signame + suffix;
173 
174  dgDEBUG(5) << "Sig <" << sig.getName() << ">: new file " << filename << endl;
175  std::ofstream *newfile = new std::ofstream(filename.c_str());
176  files.push_back(newfile);
177  dgDEBUGOUT(15);
178 }
179 
181  dgDEBUGIN(15);
182  std::lock_guard<std::mutex> files_lock(files_mtx);
183 
184  for (FileList::iterator iter = files.begin(); files.end() != iter; ++iter) {
185  std::ostream *filePtr = *iter;
186  delete filePtr;
187  }
188  files.clear();
189 
190  dgDEBUGOUT(15);
191 }
192 
193 /* --------------------------------------------------------------------- */
194 /* --------------------------------------------------------------------- */
195 /* --------------------------------------------------------------------- */
196 
198  if (!play) {
199  dgDEBUGINOUT(15);
200  return;
201  }
202 
203  dgDEBUGIN(15);
204 
205  // Ensure record() never hangs. If the attempt to acquire the lock fails,
206  // then closeFiles() is active and we shouldn't write to files anyways.
207  std::unique_lock<std::mutex> files_lock(files_mtx, std::try_to_lock);
208  if (!files_lock.owns_lock()) {
209  dgDEBUGOUT(15);
210  return;
211  }
212 
213  if (files.size() != toTraceSignals.size()) {
214  DG_THROW
215  ExceptionTraces(ExceptionTraces::NOT_OPEN, "No files open for tracing",
216  " (file=%d != %d=sig).", files.size(),
217  toTraceSignals.size());
218  }
219 
220  FileList::iterator iterFile = files.begin();
221  SignalList::iterator iterSig = toTraceSignals.begin();
222 
223  while (toTraceSignals.end() != iterSig) {
224  dgDEBUG(45) << "Try..." << endl;
225  recordSignal(**iterFile, **iterSig);
226  ++iterSig;
227  ++iterFile;
228  }
229  dgDEBUGOUT(15);
230 }
231 
232 void Tracer::recordSignal(std::ostream &os, const SignalBase<int> &sig) {
233  dgDEBUGIN(15);
234 
235  try {
236  if (sig.getTime() > timeStart) {
237  os << sig.getTime() << "\t";
238  sig.trace(os);
239  os << endl;
240  }
241  } catch (ExceptionAbstract &exc) {
242  os << exc << std::endl;
243  } catch (...) {
244  os << "Unknown error occurred while reading signal." << std::endl;
245  }
246 
247  dgDEBUGOUT(15);
248 }
249 
250 int &Tracer::recordTrigger(int &dummy, const int &time) {
251  dgDEBUGIN(15) << " time=" << time << endl;
252  record();
253  dgDEBUGOUT(15);
254  return dummy;
255 }
256 
257 void Tracer::trace() {}
258 
259 /* --------------------------------------------------------------------- */
260 /* --------------------------------------------------------------------- */
261 /* --------------------------------------------------------------------- */
262 
263 void Tracer::display(std::ostream &os) const {
264  os << CLASS_NAME << " " << name << " [mode=" << (play ? "play" : "pause")
265  << "] : " << endl
266  << " - Dep list: " << endl;
267  for (SignalList::const_iterator iter = toTraceSignals.begin();
268  toTraceSignals.end() != iter; ++iter) {
269  os << " -> " << (*iter)->getName() << endl;
270  }
271 }
272 
273 std::ostream &operator<<(std::ostream &os, const Tracer &t) {
274  t.display(os);
275  return os;
276 }
NameList names
Definition: tracer.h:54
virtual void trace(std::ostream &) const
Definition: signal-base.h:142
std::string rootdir
Definition: tracer.h:49
SignalTimeDependent< int, int > triger
Definition: tracer.h:93
std::string docDirectGetter(const std::string &name, const std::string &type)
CommandVoid0< E > * makeCommandVoid0(E &entity, boost::function< void(void)> function, const std::string &docString)
Definition: command-bind.h:51
std::string basename
Definition: tracer.h:47
DirectGetter< E, T > * makeDirectGetter(E &entity, T *ptr, const std::string &docString)
This class represents an entity, i.e. a generic computational unit that provides input and output sig...
virtual void openFile(const SignalBase< int > &sig, const std::string &filename)
Definition: tracer.cpp:163
#define dgDEBUGOUT(level)
Definition: debug.h:204
void signalRegistration(const SignalArray< int > &signals)
void openFiles(const std::string &rootdir, const std::string &basename, const std::string &suffix)
Definition: tracer.cpp:136
void addSignalToTraceByName(const std::string &signame, const std::string &filename="")
Definition: tracer.cpp:111
#define dgDEBUGINOUT(level)
Definition: debug.h:206
virtual void trace()
Definition: tracer.cpp:257
dynamicgraph::SignalArray_const< double > sig
Definition: signal-all.cpp:25
int & recordTrigger(int &dummy, const int &time)
Definition: tracer.cpp:250
std::string docCommandVoid0(const std::string &doc)
Definition: command-bind.h:70
std::string docCommandVoid3(const std::string &doc, const std::string &type1, const std::string &type2, const std::string &type3)
Definition: command-bind.h:260
const std::string & getName() const
Definition: signal-base.h:42
void clearSignalToTrace()
Definition: tracer.cpp:124
virtual void closeFiles()
Definition: tracer.cpp:180
CommandVoid3< E, T1, T2, T3 > * makeCommandVoid3(E &entity, typename CommandVoid3< E, T1, T2, T3 >::function_t function, const std::string &docString)
Definition: command-bind.h:234
void display(std::ostream &os) const
Display information on the entity inside the output stream os.
Definition: tracer.cpp:263
virtual void addDependency(const SignalBase< Time > &signal)
std::string shortName() const
Definition: signal-base.h:159
static PoolStorage * getInstance()
Get unique instance of the class.
#define dgDEBUG(level)
Definition: debug.h:157
Abstract root class for all dynamic-graph exceptions.
void dgDEBUGF(const int, const char *,...)
Definition: debug.h:169
FileList files
Definition: tracer.h:52
Tracer plug-in main class.
Definition: tracer.h:24
void addSignalToTrace(const SignalBase< int > &sig, const std::string &filename="")
Definition: tracer.cpp:99
DYNAMIC_GRAPH_DLLAPI SignalArray< int > sotNOSIGNAL
SignalList toTraceSignals
Definition: tracer.h:29
std::string docCommandVoid2(const std::string &doc, const std::string &type1, const std::string &type2)
Definition: command-bind.h:194
#define DG_THROW
std::string suffix
Definition: tracer.h:48
DYNAMICGRAPH_FACTORY_ENTITY_PLUGIN(Tracer, "Tracer")
std::mutex files_mtx
Definition: tracer.h:30
Exceptions raised when an error related to traces happen.
SignalBase< int > & getSignal(std::istringstream &sigpath)
Get a signal by name.
void addCommand(const std::string &name, command::Command *command)
Add a command to Entity.
virtual const Time & getTime() const
Definition: signal-base.h:36
virtual void recordSignal(std::ostream &os, const SignalBase< int > &sig)
Definition: tracer.cpp:232
std::string docDirectSetter(const std::string &name, const std::string &type)
DG_TRACER_DLLAPI friend std::ostream & operator<<(std::ostream &os, const Tracer &t)
Definition: tracer.cpp:273
#define dgDEBUGIN(level)
VP_DEBUG.
Definition: debug.h:202
DirectSetter< E, T > * makeDirectSetter(E &entity, T *ptr, const std::string &docString)
CommandVoid2< E, T1, T2 > * makeCommandVoid2(E &entity, boost::function< void(const T1 &, const T2 &)> function, const std::string &docString)
Definition: command-bind.h:167


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