[nemiver/profiler: 7/8] WIP on Loading of reports
- From: Fabien Parent <fparent src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/profiler: 7/8] WIP on Loading of reports
- Date: Mon, 11 Jun 2012 20:34:46 +0000 (UTC)
commit 8f4df676865c4cc85bb22dc72e5677009cc1741c
Author: Fabien Parent <parent f gmail com>
Date: Sun Jun 3 13:11:01 2012 +0200
WIP on Loading of reports
src/common/nmv-str-utils.cc | 5 +-
src/persp/profperspective/nmv-call-list.cc | 52 ++----
src/persp/profperspective/nmv-call-list.h | 3 -
.../profperspective/nmv-load-report-dialog.cc | 45 +++++-
src/persp/profperspective/nmv-load-report-dialog.h | 4 +-
src/persp/profperspective/nmv-prof-perspective.cc | 177 ++++++++++++++++++--
src/profengine/nmv-call-graph-node.cc | 48 +++---
src/profengine/nmv-call-graph-node.h | 18 +-
src/profengine/nmv-perf-engine.cc | 32 ++---
9 files changed, 274 insertions(+), 110 deletions(-)
---
diff --git a/src/common/nmv-str-utils.cc b/src/common/nmv-str-utils.cc
index 725dc5b..5817fbb 100644
--- a/src/common/nmv-str-utils.cc
+++ b/src/common/nmv-str-utils.cc
@@ -195,7 +195,10 @@ split (const UString &a_string, const UString &a_delim)
gchar **splited = g_strsplit (buf.get (), a_delim.c_str (), -1);
try {
for (gchar **cur = splited; cur && *cur; ++cur) {
- result.push_back (UString (*cur));
+ UString part = *cur;
+ if (!part.empty ()) {
+ result.push_back (part);
+ }
}
} catch (...) {
}
diff --git a/src/persp/profperspective/nmv-call-list.cc b/src/persp/profperspective/nmv-call-list.cc
index 6f5f2b4..4ceab34 100644
--- a/src/persp/profperspective/nmv-call-list.cc
+++ b/src/persp/profperspective/nmv-call-list.cc
@@ -38,14 +38,18 @@ struct CallListColumns : public Gtk::TreeModel::ColumnRecord
{
CallListColumns ()
{
- add (function_name);
- add (usage);
+ add (symbol);
+ add (overhead);
add (call_node);
+ add (command);
+ add (dso);
}
Gtk::TreeModelColumn<CallGraphNodeSafePtr> call_node;
- Gtk::TreeModelColumn<Glib::ustring> function_name;
- Gtk::TreeModelColumn<float> usage;
+ Gtk::TreeModelColumn<Glib::ustring> symbol;
+ Gtk::TreeModelColumn<float> overhead;
+ Gtk::TreeModelColumn<Glib::ustring> command;
+ Gtk::TreeModelColumn<Glib::ustring> dso;
};
struct CallList::Priv {
@@ -68,41 +72,19 @@ struct CallList::Priv {
Gtk::manage (new Gtk::CellRendererProgress);
THROW_IF_FAIL (renderer);
- treeview.append_column (_("Function"), columns.function_name);
- int usage_col_id = treeview.append_column (_("Usage"), *renderer);
+ treeview.append_column (_("Symbol"), columns.symbol);
+ treeview.append_column (_("Command"), columns.command);
+ treeview.append_column (_("Shared Object"), columns.dso);
+ int usage_col_id = treeview.append_column (_("Overhead"), *renderer);
treeview.set_model (store);
- //treeview.signal_row_activated ().connect
- // (sigc::mem_fun (*this, &CallList::Priv::on_signal_row_activated));
Gtk::TreeViewColumn *column = treeview.get_column (usage_col_id - 1);
if (column) {
- column->add_attribute (renderer->property_value(), columns.usage);
+ column->add_attribute
+ (renderer->property_value(), columns.overhead);
}
}
-/* void
- on_signal_row_activated (const Gtk::TreeModel::Path &a_path,
- Gtk::TreeViewColumn*)
- {
- NEMIVER_TRY
-
- THROW_IF_FAIL (store);
-
- Gtk::TreeModel::iterator iter = store->get_iter (a_path);
- if (!iter) {
- return;
- }
-
- CallNodeSafePtr call_node = iter->get_value (columns.call_node);
- THROW_IF_FAIL (call_node);
-
- THROW_IF_FAIL (profiler);
- profiler->annotate_source_file (call_node->filepath ());
-
- NEMIVER_CATCH
- }
-*/
-
void
add_node (CallGraphNodeSafePtr a_call_graph_node,
Gtk::TreeModel::iterator a_parent = Gtk::TreeModel::iterator ())
@@ -122,8 +104,10 @@ struct CallList::Priv {
}
if (row) {
- (*row)[columns.function_name] = (*iter)->function ();
- (*row)[columns.usage] = (*iter)->percentage ();
+ (*row)[columns.symbol] = (*iter)->symbol ();
+ (*row)[columns.overhead] = (*iter)->overhead ();
+ (*row)[columns.command] = (*iter)->command ();
+ (*row)[columns.dso] = (*iter)->shared_object ();
(*row)[columns.call_node] = *iter;
}
diff --git a/src/persp/profperspective/nmv-call-list.h b/src/persp/profperspective/nmv-call-list.h
index 436ebb5..662fac0 100644
--- a/src/persp/profperspective/nmv-call-list.h
+++ b/src/persp/profperspective/nmv-call-list.h
@@ -38,9 +38,6 @@ NEMIVER_BEGIN_NAMESPACE (nemiver)
using common::SafePtr;
-class CallNode;
-typedef CallNode CallTree;
-
class CallList {
//non copyable
CallList (const CallList&);
diff --git a/src/persp/profperspective/nmv-load-report-dialog.cc b/src/persp/profperspective/nmv-load-report-dialog.cc
index 18a8cbc..d3803a5 100644
--- a/src/persp/profperspective/nmv-load-report-dialog.cc
+++ b/src/persp/profperspective/nmv-load-report-dialog.cc
@@ -39,13 +39,38 @@ using namespace nemiver::common;
NEMIVER_BEGIN_NAMESPACE (nemiver)
-class LoadReportDialog::Priv {
+struct LoadReportDialog::Priv {
Gtk::Button *okbutton;
+ Gtk::FileChooserButton *fcbutton_report_file;
-public:
- Priv (const Glib::RefPtr<Gtk::Builder> &/*a_gtkbuilder*/) :
- okbutton (0)
+ Priv (const Glib::RefPtr<Gtk::Builder> &a_gtkbuilder) :
+ okbutton (0),
+ fcbutton_report_file (0)
{
+ okbutton = ui_utils::get_widget_from_gtkbuilder<Gtk::Button>
+ (a_gtkbuilder, "okbutton");
+ THROW_IF_FAIL (okbutton);
+ okbutton->set_sensitive (false);
+
+ fcbutton_report_file =
+ ui_utils::get_widget_from_gtkbuilder<Gtk::FileChooserButton>
+ (a_gtkbuilder, "filechooserbutton_reportfile");
+ fcbutton_report_file->signal_selection_changed ().connect
+ (sigc::mem_fun
+ (*this, &Priv::on_file_selection_changed_signal));
+ fcbutton_report_file->set_current_folder (Glib::get_current_dir ());
+ }
+
+ void on_file_selection_changed_signal ()
+ {
+ NEMIVER_TRY
+
+ THROW_IF_FAIL (fcbutton_report_file);
+ okbutton->set_sensitive (Glib::file_test
+ (fcbutton_report_file->get_filename (),
+ Glib::FILE_TEST_IS_REGULAR));
+
+ NEMIVER_CATCH
}
};//end class LoadReportDialog::Priv
@@ -59,5 +84,17 @@ LoadReportDialog::~LoadReportDialog ()
{
}
+UString
+LoadReportDialog::report_file () const
+{
+ NEMIVER_TRY
+
+ THROW_IF_FAIL (m_priv);
+ THROW_IF_FAIL (m_priv->fcbutton_report_file);
+
+ NEMIVER_CATCH
+ return m_priv->fcbutton_report_file->get_filename ();
+}
+
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/profperspective/nmv-load-report-dialog.h b/src/persp/profperspective/nmv-load-report-dialog.h
index f57011b..2ae2f07 100644
--- a/src/persp/profperspective/nmv-load-report-dialog.h
+++ b/src/persp/profperspective/nmv-load-report-dialog.h
@@ -38,13 +38,15 @@ using nemiver::common::UString;
using nemiver::common::SafePtr;
class LoadReportDialog : public Dialog {
- class Priv;
+ struct Priv;
SafePtr<Priv> m_priv;
public:
LoadReportDialog (const UString &a_resource_root_path);
virtual ~LoadReportDialog ();
+ UString report_file () const;
+
};//end class LoadReportDialog
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/persp/profperspective/nmv-prof-perspective.cc b/src/persp/profperspective/nmv-prof-perspective.cc
index 7757a7c..51e403c 100644
--- a/src/persp/profperspective/nmv-prof-perspective.cc
+++ b/src/persp/profperspective/nmv-prof-perspective.cc
@@ -26,6 +26,9 @@
#include "nmv-prof-perspective.h"
#include "nmv-ui-utils.h"
#include "nmv-load-report-dialog.h"
+#include "nmv-call-list.h"
+#include "nmv-spinner-tool-item.h"
+#include "common/nmv-safe-ptr-utils.h"
#include <list>
#include <glib/gi18n.h>
@@ -33,14 +36,39 @@
NEMIVER_BEGIN_NAMESPACE (nemiver)
+using common::DynamicModuleManager;
+using common::GCharSafePtr;
+
+static gchar *gv_report_path = 0;
+
+static const GOptionEntry entries[] =
+{
+ {
+ "load-report",
+ 0,
+ 0,
+ G_OPTION_ARG_STRING,
+ &gv_report_path,
+ _("Load a report file"),
+ "</path/to/report/file>"
+ },
+ {0, 0, 0, (GOptionArg) 0, 0, 0, 0}
+};
+
class ProfPerspective : public IProfPerspective {
//non copyable
ProfPerspective (const IProfPerspective&);
ProfPerspective& operator= (const IProfPerspective&);
+ IProfilerSafePtr prof;
+ SafePtr<CallList> call_list;
+ SafePtr<SpinnerToolItem> throbber;
+ SafePtr<Gtk::Toolbar> toolbar;
+
Glib::RefPtr<Gtk::ActionGroup> default_action_group;
Gtk::HPaned body;
IWorkbench *workbench;
+ GOptionGroup *opt_group;
sigc::signal<void, bool> signal_activated;
sigc::signal<void> signal_layout_changed;
@@ -64,38 +92,96 @@ public:
const UString &a_widget_name);
bool agree_to_shutdown ();
void init_actions ();
+ void init_signals ();
+ void init_toolbar ();
+ void init_body ();
void load_report_file ();
+ void load_report_file (const UString &a_report_file);
+
void on_load_report_file_action ();
+ void on_report_done_signal (CallGraphSafePtr a_call_graph);
+
+ IProfilerSafePtr& profiler ();
sigc::signal<void, bool>& activated_signal ();
sigc::signal<void>& layout_changed_signal ();
}; // end class ProfPerspective
ProfPerspective::ProfPerspective (DynamicModule *a_dynmod) :
- IProfPerspective (a_dynmod)
+ IProfPerspective (a_dynmod),
+ workbench (0),
+ opt_group (0)
{
+ opt_group = g_option_group_new
+ ("profiler", _("Profiler"), _("Show profiler options"), 0, 0);
+ g_option_group_add_entries (opt_group, entries);
}
GOptionGroup*
ProfPerspective::option_group () const
{
- return 0;
+ return opt_group;
}
bool
-ProfPerspective::process_options (GOptionContext */*a_context*/,
- int /*a_argc*/,
- char **/*a_argv*/)
+ProfPerspective::process_options (GOptionContext *a_context,
+ int a_argc,
+ char **/*a_argv*/)
{
+ if (a_argc && gv_report_path) {
+ std::cerr << _("You cannot provide a report file and a binary at "
+ "the same time.\n");
+ GCharSafePtr help_message;
+ help_message.reset (g_option_context_get_help
+ (a_context, true, opt_group));
+ std::cerr << help_message.get () << std::endl;
+ return false;
+ }
+
return true;
}
bool
ProfPerspective::process_gui_options (int /*a_argc*/, char **/*a_argv*/)
{
+ NEMIVER_TRY
+
+ if (gv_report_path) {
+ load_report_file (gv_report_path);
+ }
+
+ NEMIVER_CATCH
+
return true;
}
+IProfilerSafePtr&
+ProfPerspective::profiler ()
+{
+ if (!prof) {
+ DynamicModule::Loader *loader =
+ get_workbench ().get_dynamic_module ().get_module_loader ();
+ THROW_IF_FAIL (loader);
+
+ DynamicModuleManager *module_manager =
+ loader->get_dynamic_module_manager ();
+ THROW_IF_FAIL (module_manager);
+
+ UString debugger_dynmod_name;
+
+ if (debugger_dynmod_name == "") {
+ debugger_dynmod_name = "perfengine";
+ }
+ LOG_DD ("using debugger_dynmod_name: '"
+ << debugger_dynmod_name << "'");
+ prof = module_manager->load_iface<IProfiler>
+ (debugger_dynmod_name, "IProfiler");
+ }
+
+ THROW_IF_FAIL (prof);
+ return prof;
+}
+
const UString&
ProfPerspective::name () const
{
@@ -107,7 +193,10 @@ void
ProfPerspective::do_init (IWorkbench *a_workbench)
{
workbench = a_workbench;
+ init_signals ();
+ init_toolbar ();
init_actions ();
+ init_body ();
}
const UString&
@@ -118,9 +207,9 @@ ProfPerspective::get_perspective_identifier ()
}
void
-ProfPerspective::get_toolbars (std::list<Gtk::Widget*> &/*a_tbs*/)
+ProfPerspective::get_toolbars (std::list<Gtk::Widget*> &a_tbs)
{
-
+ a_tbs.push_back (toolbar.get ());
}
Gtk::Widget*
@@ -137,12 +226,62 @@ ProfPerspective::get_workbench ()
}
void
+ProfPerspective::init_toolbar ()
+{
+ throbber.reset (new SpinnerToolItem);
+ toolbar.reset ((new Gtk::Toolbar));
+ THROW_IF_FAIL (toolbar);
+
+ Glib::RefPtr<Gtk::StyleContext> style_context =
+ toolbar->get_style_context ();
+ if (style_context) {
+ style_context->add_class (GTK_STYLE_CLASS_PRIMARY_TOOLBAR);
+ }
+
+ Gtk::SeparatorToolItem *sep = Gtk::manage (new Gtk::SeparatorToolItem);
+ sep->set_draw (false);
+ sep->set_expand (true);
+ toolbar->insert (*sep, -1);
+ toolbar->insert (*throbber, -1);
+ toolbar->show ();
+}
+
+void
+ProfPerspective::init_signals ()
+{
+ THROW_IF_FAIL (profiler ());
+ profiler ()->report_done_signal ().connect (sigc::mem_fun
+ (*this, &ProfPerspective::on_report_done_signal));
+}
+
+void
+ProfPerspective::init_body ()
+{
+ body.show_all ();
+}
+
+void
+ProfPerspective::on_report_done_signal (CallGraphSafePtr a_call_graph)
+{
+ NEMIVER_TRY
+
+ call_list.reset (new CallList (profiler ()));
+ call_list->load_call_graph (a_call_graph);
+ call_list->widget ().show ();
+ body.pack1 (call_list->widget ());
+ body.show_all ();
+
+ THROW_IF_FAIL (throbber);
+ throbber->stop ();
+
+ NEMIVER_CATCH
+}
+
+void
ProfPerspective::init_actions ()
{
Gtk::StockID nil_stock_id ("");
sigc::slot<void> nil_slot;
- Glib::RefPtr<Gtk::UIManager> uimanager = get_workbench ().get_ui_manager ();
- THROW_IF_FAIL (uimanager);
static ui_utils::ActionEntry s_default_action_entries [] = {
{
@@ -167,10 +306,9 @@ ProfPerspective::init_actions ()
ui_utils::add_action_entries_to_action_group
(s_default_action_entries, num_actions, default_action_group);
+ Glib::RefPtr<Gtk::UIManager> uimanager = get_workbench ().get_ui_manager ();
+ THROW_IF_FAIL (uimanager);
uimanager->insert_action_group (default_action_group);
-
- get_workbench ().get_root_window ().add_accel_group
- (uimanager->get_accel_group ());
}
std::list<Gtk::UIManager::ui_merge_id>
@@ -192,6 +330,17 @@ ProfPerspective::edit_workbench_menu ()
}
void
+ProfPerspective::load_report_file (const UString &a_report_file)
+{
+ THROW_IF_FAIL (!a_report_file.empty ());
+ THROW_IF_FAIL (profiler ());
+ profiler ()->report (a_report_file);
+
+ THROW_IF_FAIL (throbber);
+ throbber->start ();
+}
+
+void
ProfPerspective::load_report_file ()
{
LoadReportDialog dialog (plugin_path ());
@@ -200,6 +349,10 @@ ProfPerspective::load_report_file ()
if (result != Gtk::RESPONSE_OK) {
return;
}
+
+ UString report_file = dialog.report_file ();
+ THROW_IF_FAIL (!report_file.empty ());
+ load_report_file (report_file);
}
void
diff --git a/src/profengine/nmv-call-graph-node.cc b/src/profengine/nmv-call-graph-node.cc
index b2ac0aa..06f83ff 100644
--- a/src/profengine/nmv-call-graph-node.cc
+++ b/src/profengine/nmv-call-graph-node.cc
@@ -31,10 +31,10 @@ NEMIVER_BEGIN_NAMESPACE (nemiver)
struct CallGraphNode::Priv {
std::list<CallGraphNodeSafePtr> children;
CallGraphNodeSafePtr parent;
- unsigned cost;
- UString filepath;
- UString function;
- float percentage;
+ UString command;
+ UString shared_object;
+ UString symbol;
+ float overhead;
Priv () :
parent (0)
@@ -90,60 +90,60 @@ CallGraphNode::add_child (const CallGraphNodeSafePtr &a_node)
m_priv->children.push_back (a_node);
}
-float
-CallGraphNode::percentage () const
+const float&
+CallGraphNode::overhead () const
{
THROW_IF_FAIL (m_priv);
- return m_priv->percentage;
+ return m_priv->overhead;
}
void
-CallGraphNode::percentage (const float &a_percentage)
+CallGraphNode::overhead (const float &a_overhead)
{
THROW_IF_FAIL (m_priv);
- m_priv->percentage = a_percentage;
+ m_priv->overhead = a_overhead;
}
-unsigned
-CallGraphNode::cost () const
+const UString&
+CallGraphNode::symbol () const
{
THROW_IF_FAIL (m_priv);
- return m_priv->cost;
+ return m_priv->symbol;
}
void
-CallGraphNode::cost (unsigned a_cost)
+CallGraphNode::symbol (const UString &a_symbol)
{
THROW_IF_FAIL (m_priv);
- m_priv->cost = a_cost;
+ m_priv->symbol = a_symbol;
}
-UString&
-CallGraphNode::filepath () const
+const UString&
+CallGraphNode::command () const
{
THROW_IF_FAIL (m_priv);
- return m_priv->filepath;
+ return m_priv->command;
}
void
-CallGraphNode::filepath (const UString &a_filepath)
+CallGraphNode::command (const UString &a_command)
{
THROW_IF_FAIL (m_priv);
- m_priv->filepath = a_filepath;
+ m_priv->command = a_command;
}
-UString&
-CallGraphNode::function () const
+const UString&
+CallGraphNode::shared_object () const
{
THROW_IF_FAIL (m_priv);
- return m_priv->function;
+ return m_priv->shared_object;
}
void
-CallGraphNode::function (const UString &a_function)
+CallGraphNode::shared_object (const UString &a_shared_object)
{
THROW_IF_FAIL (m_priv);
- m_priv->function = a_function;
+ m_priv->shared_object = a_shared_object;
}
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/profengine/nmv-call-graph-node.h b/src/profengine/nmv-call-graph-node.h
index 14587d0..c18048b 100644
--- a/src/profengine/nmv-call-graph-node.h
+++ b/src/profengine/nmv-call-graph-node.h
@@ -61,19 +61,17 @@ public:
const std::list<CallGraphNodeSafePtr>& children () const;
void add_child (const CallGraphNodeSafePtr&);
- float percentage () const;
- void percentage (const float&);
+ const float& overhead () const;
+ void overhead (const float&);
- unsigned cost () const;
- void cost (unsigned);
+ const UString& command () const;
+ void command (const UString&);
- UString& filepath () const;
- void filepath (const UString &a_filepath);
+ const UString& shared_object () const;
+ void shared_object (const UString&);
- UString& function () const;
- void function (const UString &a_function);
-
-
+ const UString& symbol () const;
+ void symbol (const UString&);
}; // end namespace CallGraphNode
NEMIVER_END_NAMESPACE (nemiver)
diff --git a/src/profengine/nmv-perf-engine.cc b/src/profengine/nmv-perf-engine.cc
index 66cff03..2022d77 100644
--- a/src/profengine/nmv-perf-engine.cc
+++ b/src/profengine/nmv-perf-engine.cc
@@ -49,11 +49,6 @@ struct PerfEngine::Priv {
sigc::signal<void, CallGraphSafePtr> report_done_signal;
-/*
- Glib::RefPtr<Glib::MainContext> event_context;
- sigc::signal<void> program_exited_signal;
- sigc::signal<void, const AnnotatedSourceFile&> annotation_done_signal;
-*/
Priv () :
perf_pid (0),
master_pty_fd (0),
@@ -96,16 +91,18 @@ struct PerfEngine::Priv {
parse_top_level_symbol (std::vector<UString> &a_tokens)
{
THROW_IF_FAIL (a_tokens.size ());
- THROW_IF_FAIL (a_tokens[0].size ());
+ THROW_IF_FAIL (a_tokens[0].size () >= 4);
- float percentage = 0.0;
+ float overhead = 0.0;
std::istringstream is (a_tokens[0].substr(0, a_tokens[0].size () - 1));
- is >> percentage;
+ is >> overhead;
CallGraphNodeSafePtr node (new CallGraphNode);
THROW_IF_FAIL (node);
- node->percentage (percentage);
- node->function (a_tokens[a_tokens.size () - 1]);
+ node->overhead (overhead);
+ node->command (a_tokens[1]);
+ node->shared_object (a_tokens[2]);
+ node->symbol (a_tokens[a_tokens.size () - 1]);
call_graph->add_child (node);
while (call_stack.size ()) {
@@ -140,26 +137,19 @@ struct PerfEngine::Priv {
}
THROW_IF_FAIL (call_stack.size ());
- if (a_tokens.size () < 2) {
- for (size_t i = 0; i < a_tokens[0].size (); i++) {
- std::cout << std::hex << a_tokens[0][i] << " " << std::endl;
- }
- std::cout << std::endl;
- }
-
THROW_IF_FAIL (a_tokens.size () >= 2);
if (a_tokens[a_tokens.size () - 2].find ("--") == std::string::npos) {
return;
}
- float percentage = 0.0;
+ float overhead = 0.0;
std::istringstream is (a_tokens[a_tokens.size () - 2].substr (3));
- is >> percentage;
+ is >> overhead;
CallGraphNodeSafePtr node (new CallGraphNode);
THROW_IF_FAIL (node);
- node->percentage (percentage);
- node->function (a_tokens[a_tokens.size () - 1]);
+ node->overhead (overhead);
+ node->symbol (a_tokens[a_tokens.size () - 1]);
THROW_IF_FAIL (call_stack.top ());
call_stack.top ()->add_child (node);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]