26#if defined (HAVE_CONFIG_H)
40profiler::stats::stats ()
41 : m_time (0.0), m_calls (0), m_recursive (false),
42 m_parents (), m_children ()
46profiler::stats::function_set_value (
const function_set& list)
52 for (
const auto& nm : list)
59 : m_parent (p), m_fcn_id (
f), m_children (), m_time (0.0), m_calls (0)
62profiler::tree_node::~tree_node ()
64 for (
auto& idx_tnode : m_children)
65 delete idx_tnode.second;
73 child_map::iterator pos = m_children.find (fcn);
74 if (pos == m_children.end ())
76 retval =
new tree_node (
this, fcn);
77 m_children[fcn] = retval;
93profiler::tree_node::build_flat (flat_profile& data)
const
99 stats& entry = data[m_fcn_id - 1];
101 entry.m_time += m_time;
102 entry.m_calls += m_calls;
105 error (
"unexpected: m_parent is nullptr in profiler::tree_node::build_flat - please report this bug");
107 if (m_parent->m_fcn_id != 0)
109 entry.m_parents.insert (m_parent->m_fcn_id);
110 data[m_parent->m_fcn_id - 1].m_children.insert (m_fcn_id);
113 if (! entry.m_recursive)
114 for (
const tree_node *i = m_parent; i; i = i->m_parent)
115 if (i->m_fcn_id == m_fcn_id)
117 entry.m_recursive =
true;
123 for (
const auto& idx_tnode : m_children)
124 idx_tnode.second->build_flat (data);
128profiler::tree_node::get_hierarchical (
double *total)
const
137 Cell rv_indices (n, 1);
138 Cell rv_times (n, 1);
139 Cell rv_totals (n, 1);
140 Cell rv_calls (n, 1);
141 Cell rv_children (n, 1);
144 for (
const auto& idx_tnode : m_children)
146 const tree_node& entry = *idx_tnode.second;
147 double child_total = entry.m_time;
152 rv_children(i) = entry.get_hierarchical (&child_total);
156 *total += child_total;
163 retval.
assign (
"Index", rv_indices);
164 retval.
assign (
"SelfTime", rv_times);
165 retval.
assign (
"TotalTime", rv_totals);
166 retval.
assign (
"NumCalls", rv_calls);
167 retval.
assign (
"Children", rv_children);
173 : m_known_functions (), m_fcn_index (),
174 m_enabled (false), m_call_tree (new tree_node (nullptr, 0)),
175 m_active_fcn (nullptr), m_last_time (-1.0)
190profiler::enter_function (
const std::string& fcn)
194 error (
"unexpected: profiler not enabled in profiler::enter_function - please report this bug");
197 error (
"unexpected: m_call_tree is nullptr in profiler::enter_function - please report this bug");
201 if (m_active_fcn && m_active_fcn != m_call_tree)
206 fcn_index_map::iterator pos = m_fcn_index.find (fcn);
207 if (pos == m_fcn_index.end ())
209 m_known_functions.push_back (fcn);
210 fcn_idx = m_known_functions.size ();
211 m_fcn_index[fcn] = fcn_idx;
214 fcn_idx = pos->second;
217 m_active_fcn = m_call_tree;
219 m_active_fcn = m_active_fcn->enter (fcn_idx);
221 m_last_time = query_time ();
226profiler::exit_function (
const std::string& fcn)
231 error (
"unexpected: m_call_tree is nullptr in profiler::enter_function - please report this bug");
239 fcn_index_map::iterator pos = m_fcn_index.find (fcn);
241 m_active_fcn = m_active_fcn->exit (pos->second);
245 m_last_time = query_time ();
253 error (
"profile: can't reset active profiler");
255 m_known_functions.clear ();
256 m_fcn_index.clear ();
261 m_call_tree =
new tree_node (
nullptr, 0);
262 m_active_fcn =
nullptr;
275 flat_profile flat (n);
279 m_call_tree->build_flat (flat);
281 Cell rv_names (n, 1);
282 Cell rv_times (n, 1);
283 Cell rv_calls (n, 1);
284 Cell rv_recursive (n, 1);
285 Cell rv_parents (n, 1);
286 Cell rv_children (n, 1);
294 rv_parents(i) = stats::function_set_value (flat[i].m_parents);
295 rv_children(i) = stats::function_set_value (flat[i].m_children);
300 m.
assign (
"FunctionName", rv_names);
301 m.
assign (
"TotalTime", rv_times);
302 m.
assign (
"NumCalls", rv_calls);
303 m.
assign (
"IsRecursive", rv_recursive);
304 m.
assign (
"Parents", rv_parents);
305 m.
assign (
"Children", rv_children);
311 static const char *fn[] =
336 retval = m_call_tree->get_hierarchical ();
339 static const char *fn[] =
357profiler::query_time ()
const
361 return now.double_value ();
365profiler::add_current_time ()
369 const double t = query_time ();
371 m_active_fcn->add_time (t - m_last_time);
376DEFMETHOD (__profiler_enable__, interp, args, ,
382 int nargin = args.length ();
393 std::string status =
"off";
394 if (args(0).bool_value ())
405DEFMETHOD (__profiler_reset__, interp, args, ,
411 if (args.length () != 0)
422DEFMETHOD (__profiler_data__, interp, args, nargout,
428 if (args.length () != 0)
439OCTAVE_END_NAMESPACE(octave)
Vector representing the dimensions (size) of an Array.
Provides threadsafe access to octave.
bool gui_status_update(const std::string &feature, const std::string &status)
void assign(const std::string &k, const Cell &val)
octave_value get_flat() const
octave_value get_hierarchical() const
OCTAVE_BEGIN_NAMESPACE(octave) static octave_value daspk_fcn
#define DEFMETHOD(name, interp_name, args_name, nargout_name, doc)
Macro to define a builtin method.
void error(const char *fmt,...)
F77_RET_T const F77_DBLE const F77_DBLE * f
octave_value_list ovl(const OV_Args &... args)
Construct an octave_value_list with less typing.