[nemiver/profiler: 7/8] WIP on Loading of reports



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]