[nemiver/profiler: 40/48] WIP
- From: Fabien Parent <fparent src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nemiver/profiler: 40/48] WIP
- Date: Wed, 15 Aug 2012 10:02:01 +0000 (UTC)
commit 8319f5e32cce79d8c7cf26e965e76a545c665ef8
Author: Fabien Parent <parent f gmail com>
Date: Sun Aug 5 16:00:57 2012 +0200
WIP
src/persp/profperspective/nmv-prof-perspective.cc | 7 +-
src/persp/profperspective/nmv-record-options.h | 51 +++++
src/profengine/Makefile.am | 17 +-
src/profengine/nmv-confmgr-record-options.cc | 123 +++++++++++
src/profengine/nmv-confmgr-record-options.h | 59 +++++
src/profengine/nmv-i-profiler.h | 4 +-
src/profengine/nmv-perf-engine.cc | 86 ++------
src/profengine/nmv-perf-engine.h | 6 +-
src/profengine/nmv-perf-server.cc | 243 ++++++++++++---------
src/profengine/nmv-record-options.h | 57 +++++
10 files changed, 476 insertions(+), 177 deletions(-)
---
diff --git a/src/persp/profperspective/nmv-prof-perspective.cc b/src/persp/profperspective/nmv-prof-perspective.cc
index f9c9f33..ae74941 100644
--- a/src/persp/profperspective/nmv-prof-perspective.cc
+++ b/src/persp/profperspective/nmv-prof-perspective.cc
@@ -31,6 +31,7 @@
#include "nmv-spinner-tool-item.h"
#include "nmv-run-program-dialog.h"
#include "nmv-i-profiler.h"
+#include "nmv-confmgr-record-options.h"
#include "common/nmv-safe-ptr-utils.h"
#include "common/nmv-str-utils.h"
#include "common/nmv-proc-mgr.h"
@@ -578,7 +579,11 @@ ProfPerspective::run_executable (const UString &a_program_name,
THROW_IF_FAIL (!a_program_name.empty ());
THROW_IF_FAIL (profiler ());
- profiler ()->record (a_program_name, argv);
+ IConfMgrSafePtr confmgr = get_workbench ().get_configuration_manager ();
+ THROW_IF_FAIL (confmgr);
+
+ ConfMgrRecordOptions options (*confmgr);
+ profiler ()->record (a_program_name, argv, options);
THROW_IF_FAIL (throbber);
throbber->start ();
diff --git a/src/persp/profperspective/nmv-record-options.h b/src/persp/profperspective/nmv-record-options.h
new file mode 100644
index 0000000..3e2522a
--- /dev/null
+++ b/src/persp/profperspective/nmv-record-options.h
@@ -0,0 +1,51 @@
+//Author: Fabien Parent
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+#ifndef __NMV_RECORD_OPTIONS_H__
+#define __NMV_RECORD_OPTIONS_H__
+
+#include "common/nmv-namespace.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class RecordOptions {
+ RecordOptions ();
+ RecordOptions (const RecordOptions&);
+ RecordOptions& operator= (const RecordOptions&);
+
+public:
+ virtual ~RecordOptions ();
+
+ virtual bool do_callgraph_recording () const = 0;
+ virtual bool do_collect_without_buffering () const = 0;
+ virtual bool do_collect_raw_sample_records () const = 0;
+ virtual bool do_system_wide_collection () const = 0;
+ virtual bool do_sample_addresses () const = 0;
+ virtual bool do_sample_timestamps () const = 0;
+}; // end namespace RecordOptions
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif /* __NMV_RECORD_OPTIONS_H__ */
+
diff --git a/src/profengine/Makefile.am b/src/profengine/Makefile.am
index 9408476..75e7b3c 100644
--- a/src/profengine/Makefile.am
+++ b/src/profengine/Makefile.am
@@ -2,7 +2,8 @@ perfmod_LTLIBRARIES=libperfmod.la
perfmoddir= NEMIVER_MODULES_DIR@
noinst_LTLIBRARIES=\
-libperfengine.la
+libperfengine.la \
+libperfcommon.la
h=$(abs_srcdir)
@@ -15,19 +16,25 @@ $(iprofilerheaders)
libperfmod_la_SOURCES= \
$(iprofilerheaders)
-libperfengine_la_SOURCES= \
+libperfcommon_la_SOURCES= \
$(h)/nmv-perf-engine.cc \
$(h)/nmv-perf-engine.h \
+$(h)/nmv-record-options.h \
$(h)/nmv-call-graph-node.cc \
$(h)/nmv-call-graph-node.h
+libperfcommon_la_CFLAGS=-fPIC -DPIC
+libperfengine_la_SOURCES= \
+$(h)/nmv-confmgr-record-options.h \
+$(h)/nmv-confmgr-record-options.cc
libperfengine_la_CFLAGS=-fPIC -DPIC
publicheaders_DATA=$(dynmodheaders)
publicheadersdir=$(NEMIVER_INCLUDE_DIR)/dynmods
libperfmod_la_LDFLAGS=-module -avoid-version -Wl,--as-needed
-libperfmod_la_LIBADD=libperfengine.la @NEMIVERCOMMON_LIBS@ \
+libperfmod_la_LIBADD=libperfcommon.la libperfengine.la \
+ NEMIVERCOMMON_LIBS@ \
@NEMIVERPROFPERSP_LIBS@ \
$(abs_top_builddir)/src/common/libnemivercommon.la
@@ -36,10 +43,10 @@ config_DATA=perfengine.conf
configdir= NEMIVER_SYSTEM_CONFIG_DIR@
bin_PROGRAMS=nmvperfserver
-nmvperfserver_SOURCES= $(h)/nmv-perf-server.cc
+nmvperfserver_SOURCES=$(h)/nmv-perf-server.cc
nmvperfserver= NEMIVER_MODULES_DIR@
nmvperfserver_LDADD= NEMIVERPROFPERSP_LIBS@ \
-$(abs_top_builddir)/src/common/libnemivercommon.la
+$(abs_top_builddir)/src/common/libnemivercommon.la libperfcommon.la
service_DATA=org.gnome.nemiver.profiler.service
servicedir=$(datadir)/dbus-1/system-services
diff --git a/src/profengine/nmv-confmgr-record-options.cc b/src/profengine/nmv-confmgr-record-options.cc
new file mode 100644
index 0000000..72a8daf
--- /dev/null
+++ b/src/profengine/nmv-confmgr-record-options.cc
@@ -0,0 +1,123 @@
+// Author: Fabien Parent
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+
+#include "nmv-confmgr-record-options.h"
+#include "nmv-conf-keys.h"
+#include "nmv-i-conf-mgr.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+struct ConfMgrRecordOptions::Priv {
+ IConfMgr &conf_mgr;
+
+ Priv (IConfMgr &a_confmgr) :
+ conf_mgr (a_confmgr)
+ {
+ }
+};
+
+ConfMgrRecordOptions::ConfMgrRecordOptions (IConfMgr &a_confmgr) :
+ m_priv (new Priv (a_confmgr))
+{
+}
+
+ConfMgrRecordOptions::~ConfMgrRecordOptions ()
+{
+}
+
+bool
+ConfMgrRecordOptions::do_callgraph_recording () const
+{
+ bool callgraph_recording = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_DO_CALLGRAPH_RECORDING,
+ callgraph_recording)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_DO_CALLGRAPH_RECORDING);
+ }
+ return callgraph_recording;
+}
+
+bool
+ConfMgrRecordOptions::do_collect_without_buffering () const
+{
+ bool collect_without_buffering = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_COLLECT_WITHOUT_BUFFERING,
+ collect_without_buffering)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_COLLECT_WITHOUT_BUFFERING);
+ }
+ return collect_without_buffering;
+}
+
+bool
+ConfMgrRecordOptions::do_collect_raw_sample_records () const
+{
+ bool collect_raw_sample_records = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_COLLECT_RAW_SAMPLE_RECORDS,
+ collect_raw_sample_records)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_COLLECT_RAW_SAMPLE_RECORDS);
+ }
+ return collect_raw_sample_records;
+}
+
+bool
+ConfMgrRecordOptions::do_system_wide_collection () const
+{
+ bool system_wide_collection = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_SYSTEM_WIDE_COLLECTION,
+ system_wide_collection)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_SYSTEM_WIDE_COLLECTION);
+ }
+ return system_wide_collection;
+}
+
+bool
+ConfMgrRecordOptions::do_sample_addresses () const
+{
+ bool sample_addresses = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_SAMPLE_ADDRESSES,
+ sample_addresses)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_SAMPLE_ADDRESSES);
+ }
+ return sample_addresses;
+}
+
+bool
+ConfMgrRecordOptions::do_sample_timestamps () const
+{
+ bool sample_timestamps = false;
+ if (!m_priv->conf_mgr.get_key_value (CONF_KEY_SAMPLE_TIMESTAMPS,
+ sample_timestamps)) {
+ LOG_ERROR ("failed to get gconf key "
+ << CONF_KEY_SAMPLE_TIMESTAMPS);
+ }
+ return sample_timestamps;
+}
+
+NEMIVER_END_NAMESPACE (nemiver)
+
diff --git a/src/profengine/nmv-confmgr-record-options.h b/src/profengine/nmv-confmgr-record-options.h
new file mode 100644
index 0000000..ea44d1e
--- /dev/null
+++ b/src/profengine/nmv-confmgr-record-options.h
@@ -0,0 +1,59 @@
+//Author: Fabien Parent
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+#ifndef __NMV_CONFMGR_RECORD_OPTIONS_H__
+#define __NMV_CONFMGR_RECORD_OPTIONS_H__
+
+#include "nmv-record-options.h"
+#include "common/nmv-safe-ptr.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class IConfMgr;
+
+using common::SafePtr;
+
+class ConfMgrRecordOptions : public RecordOptions {
+ ConfMgrRecordOptions (const RecordOptions&);
+ ConfMgrRecordOptions& operator= (const RecordOptions&);
+
+ struct Priv;
+ SafePtr<Priv> m_priv;
+
+public:
+ ConfMgrRecordOptions (IConfMgr&);
+ virtual ~ConfMgrRecordOptions ();
+
+ bool do_callgraph_recording () const;
+ bool do_collect_without_buffering () const;
+ bool do_collect_raw_sample_records () const;
+ bool do_system_wide_collection () const;
+ bool do_sample_addresses () const;
+ bool do_sample_timestamps () const;
+}; // end namespace ConfMgrRecordOptions
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif /* __NMV_CONFMGR_RECORD_OPTIONS_H__ */
+
diff --git a/src/profengine/nmv-i-profiler.h b/src/profengine/nmv-i-profiler.h
index 581cbc0..f728cab 100644
--- a/src/profengine/nmv-i-profiler.h
+++ b/src/profengine/nmv-i-profiler.h
@@ -32,6 +32,7 @@
#include "nmv-i-conf-mgr.h"
#include "nmv-i-profiler.h"
#include "nmv-call-graph-node.h"
+#include "nmv-record-options.h"
using nemiver::common::SafePtr;
using nemiver::common::DynamicModule;
@@ -79,7 +80,8 @@ public:
virtual void report (const UString &a_data_file) = 0;
virtual void record (const UString &a_program_path,
- const std::vector<UString> &a_argv) = 0;
+ const std::vector<UString> &a_argv,
+ const RecordOptions &a_options) = 0;
virtual void stop_recording () = 0;
diff --git a/src/profengine/nmv-perf-engine.cc b/src/profengine/nmv-perf-engine.cc
index df2bc07..8145430 100644
--- a/src/profengine/nmv-perf-engine.cc
+++ b/src/profengine/nmv-perf-engine.cc
@@ -25,7 +25,6 @@
#include "nmv-perf-engine.h"
#include "nmv-call-graph-node.h"
-#include "nmv-conf-keys.h"
#include "common/nmv-proc-utils.h"
#include "common/nmv-str-utils.h"
#include <istream>
@@ -65,6 +64,7 @@ struct PerfEngine::Priv {
sigc::signal<void, const UString&, const UString&> symbol_annotated_signal;
bool is_using_prof_server;
+ unsigned request_id;
Glib::RefPtr<Gio::DBus::Connection> server_connection;
Glib::RefPtr<Gio::DBus::Proxy> proxy;
@@ -393,108 +393,67 @@ PerfEngine::attach_to_pid (int a_pid)
Glib::Variant<int> pid_param = Glib::Variant<int>::create (a_pid);
Glib::Variant<int> uid_param = Glib::Variant<int>::create (getuid ());
Glib::Variant<int> gid_param = Glib::Variant<int>::create (a_pid);
- Glib::Variant<std::vector<Glib::ustring> > options_param =
- Glib::Variant<std::vector<Glib::ustring> >::create (options);
std::vector<Glib::VariantBase> parameters;
parameters.push_back (pid_param);
parameters.push_back (uid_param);
parameters.push_back (gid_param);
- parameters.push_back (options_param);
Glib::VariantContainerBase parameters_variant =
Glib::VariantContainerBase::create_tuple (parameters);
+ Glib::VariantContainerBase response;
m_priv->is_using_prof_server = true;
+ response = m_priv->proxy->call_sync ("AttachToPID", parameters_variant);
+
+ Glib::Variant<unsigned> request_id_param;
+ response.get_child (request_id_param);
+ m_priv->request_id = request_id_param.get ();
+
+ parameters.clear ();
+ parameters.push_back (request_id_param);
+ parameters_variant = Glib::VariantContainerBase::create_tuple (parameters);
m_priv->proxy->call
- ("AttachToPID",
+ ("RecordDoneSignal",
sigc::mem_fun (*m_priv, &PerfEngine::Priv::on_detached_from_process),
parameters_variant);
-
-/* std::vector<UString> argv;
- argv.push_back ("--pid");
- argv.push_back (UString::compose ("%1", a_pid));
-
- record (argv);
-*/
}
void
-PerfEngine::record (const std::vector<UString> &a_argv)
+PerfEngine::record (const std::vector<UString> &a_argv,
+ const RecordOptions &a_options)
{
SafePtr<char, DefaultRef, FreeUnref> tmp_filepath (tempnam(0, 0));
THROW_IF_FAIL (tmp_filepath);
THROW_IF_FAIL (m_priv);
m_priv->record_filepath = tmp_filepath.get ();
- bool do_callgraph_recording = true;
- bool do_collect_without_buffering = false;
- bool do_collect_raw_sample_records = false;
- bool do_system_wide_collection = false;
- bool do_sample_addresses = false;
- bool do_sample_timestamps = false;
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_DO_CALLGRAPH_RECORDING,
- do_callgraph_recording)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_DO_CALLGRAPH_RECORDING);
- }
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_COLLECT_WITHOUT_BUFFERING,
- do_collect_without_buffering)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_COLLECT_WITHOUT_BUFFERING);
- }
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_COLLECT_RAW_SAMPLE_RECORDS,
- do_collect_raw_sample_records)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_COLLECT_RAW_SAMPLE_RECORDS);
- }
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_SYSTEM_WIDE_COLLECTION,
- do_system_wide_collection)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_SYSTEM_WIDE_COLLECTION);
- }
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_SAMPLE_ADDRESSES,
- do_sample_addresses)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_SAMPLE_ADDRESSES);
- }
-
- if (!m_priv->conf_mgr ().get_key_value (CONF_KEY_SAMPLE_TIMESTAMPS,
- do_sample_timestamps)) {
- LOG_ERROR ("failed to get gconf key "
- << CONF_KEY_SAMPLE_TIMESTAMPS);
- }
std::vector<UString> argv;
argv.push_back ("perf");
argv.push_back ("record");
- if (do_callgraph_recording) {
+ if (a_options.do_callgraph_recording ()) {
argv.push_back ("--call-graph");
}
- if (do_collect_without_buffering) {
+ if (a_options.do_collect_without_buffering ()) {
argv.push_back ("--no-delay");
}
- if (do_collect_raw_sample_records) {
+ if (a_options.do_collect_raw_sample_records ()) {
argv.push_back ("--raw-samples");
}
- if (do_system_wide_collection) {
+ if (a_options.do_system_wide_collection ()) {
argv.push_back ("--all-cpus");
}
- if (do_sample_addresses) {
+ if (a_options.do_sample_addresses ()) {
argv.push_back ("--data");
}
- if (do_sample_timestamps) {
+ if (a_options.do_sample_timestamps ()) {
argv.push_back ("--timestamp");
}
@@ -517,14 +476,15 @@ PerfEngine::record (const std::vector<UString> &a_argv)
void
PerfEngine::record (const UString &a_program_path,
- const std::vector<UString> &a_argv)
+ const std::vector<UString> &a_argv,
+ const RecordOptions &a_options)
{
std::vector<UString> argv;
argv.push_back ("--");
argv.push_back (a_program_path);
argv.insert (argv.end (), a_argv.begin (), a_argv.end ());
- record (argv);
+ record (argv, a_options);
}
void
diff --git a/src/profengine/nmv-perf-engine.h b/src/profengine/nmv-perf-engine.h
index e1616c9..25bfd15 100644
--- a/src/profengine/nmv-perf-engine.h
+++ b/src/profengine/nmv-perf-engine.h
@@ -44,9 +44,11 @@ public:
void report (const UString &a_data_file);
void attach_to_pid (int a_pid);
- void record (const std::vector<UString> &a_argv);
+ void record (const std::vector<UString> &a_argv,
+ const RecordOptions &a_options);
void record (const UString &a_program_path,
- const std::vector<UString> &a_argv);
+ const std::vector<UString> &a_argv,
+ const RecordOptions &a_options);
void stop_recording ();
void annotate_symbol (const UString &a_symbol_name);
diff --git a/src/profengine/nmv-perf-server.cc b/src/profengine/nmv-perf-server.cc
index 8f737f0..5e2589c 100644
--- a/src/profengine/nmv-perf-server.cc
+++ b/src/profengine/nmv-perf-server.cc
@@ -28,6 +28,8 @@
#include "common/nmv-exception.h"
#include "common/nmv-ustring.h"
#include "common/nmv-proc-utils.h"
+#include "nmv-record-options.h"
+#include "nmv-perf-engine.h"
#include <glibmm.h>
#include <giomm.h>
@@ -53,14 +55,68 @@ static const char *const NMV_DBUS_PROFILER_SERVER_INTROSPECTION_DATA =
" <arg type='i' name='uid' direction='in' />"
" <arg type='i' name='gid' direction='in' />"
// " <arg type='u' name='cookie' direction='in' />"
- " <arg type='as' name='arguments' direction='in' />"
- " <arg type='s' name='data_filepath' direction='out' />"
+ " <arg type='i' name='request_id' direction='out' />"
" </method>"
" <method name='DetachFromProcess'>"
+ " <arg type='i' name='request_id' direction='in' />"
+ " </method>"
+ " <method name='RecordDoneSignal'>"
+ " <arg type='i' name='request_id' direction='in' />"
+ " <arg type='s' name='report_filepath' direction='out' />"
" </method>"
" </interface>"
"</node>";
+class PerfRecordOptions : public RecordOptions {
+ bool callgraph_recording;
+ bool collect_without_buffering;
+ bool collect_raw_sample_records;
+ bool system_wide_collection;
+ bool sample_addresses;
+ bool sample_timestamps;
+
+public:
+ PerfRecordOptions () :
+ callgraph_recording (true),
+ collect_without_buffering (false),
+ collect_raw_sample_records (false),
+ system_wide_collection (false),
+ sample_addresses (false),
+ sample_timestamps (false)
+ {
+ }
+
+ bool do_callgraph_recording () const
+ {
+ return callgraph_recording;
+ }
+
+ bool do_collect_without_buffering () const
+ {
+ return collect_without_buffering;
+ }
+
+ bool do_collect_raw_sample_records () const
+ {
+ return collect_raw_sample_records;
+ }
+
+ bool do_system_wide_collection () const
+ {
+ return system_wide_collection;
+ }
+
+ bool do_sample_addresses () const
+ {
+ return sample_addresses;
+ }
+
+ bool do_sample_timestamps () const
+ {
+ return sample_timestamps;
+ }
+}; // end namespace PerfRecordOptions
+
class PerfServer {
PerfServer (const PerfServer &);
@@ -75,17 +131,27 @@ public:
~PerfServer ();
}; // end namespace PerfServer
+struct RequestInfo {
+ int gid;
+ int uid;
+ SafePtr<PerfEngine> profiler;
+ Glib::RefPtr<Gio::DBus::MethodInvocation> invocation;
+
+ RequestInfo () :
+ profiler (new PerfEngine (0)),
+ invocation (0)
+ {
+ }
+};
+
struct PerfServer::Priv {
// PolkitSubject *subject;
- unsigned int bus_id;
- unsigned int registration_id;
+ unsigned bus_id;
+ unsigned registration_id;
Glib::RefPtr<Gio::DBus::NodeInfo> introspection_data;
Gio::DBus::InterfaceVTable interface_vtable;
-
- int perf_pid;
- int master_pty_fd;
- int perf_stdout_fd;
- int perf_stderr_fd;
+ std::map<int, RequestInfo> request_map;
+ unsigned next_request_id;
Priv () :
// subject (polkit_system_bus_name_new ("org.gnome.Nemiver")),
@@ -94,53 +160,11 @@ struct PerfServer::Priv {
introspection_data (0),
interface_vtable
(sigc::mem_fun (*this, &PerfServer::Priv::on_new_request)),
- perf_pid (0),
- master_pty_fd (0),
- perf_stdout_fd (0),
- perf_stderr_fd (0)
+ next_request_id (0)
{
init ();
}
- bool
- on_wait_for_record_to_exit (int a_uid, int a_gid,
- Glib::RefPtr<Gio::DBus::MethodInvocation>
- a_invocation,
- Glib::ustring a_report_filepath)
- {
- int status = 0;
- pid_t pid = waitpid (perf_pid, &status, WNOHANG);
- bool is_terminated = WIFEXITED (status) || WIFSIGNALED (status);
-
- if (pid == perf_pid && is_terminated) {
- g_spawn_close_pid (perf_pid);
- perf_pid = 0;
- master_pty_fd = 0;
- perf_stdout_fd = 0;
- perf_stderr_fd = 0;
-
- NEMIVER_TRY;
-
- Glib::Variant<Glib::ustring> perf_data =
- Glib::Variant<Glib::ustring>::create (a_report_filepath);
-
- Glib::VariantContainerBase response =
- Glib::VariantContainerBase::create_tuple (perf_data);
-
- chown (a_report_filepath.c_str (), a_uid, a_gid);
-
- std::cout << "Saving report to " << a_report_filepath << std::endl;
-
- a_invocation->return_value (response);
-
- NEMIVER_CATCH_NOX;
-
- return false;
- }
-
- return true;
- }
-
void
on_new_request (const Glib::RefPtr<Gio::DBus::Connection> &a_connection,
const Glib::ustring&,
@@ -160,69 +184,56 @@ struct PerfServer::Priv {
Glib::Variant<int> pid_param;
Glib::Variant<int> uid_param;
Glib::Variant<int> gid_param;
- Glib::Variant<std::vector<Glib::ustring> > options_param;
a_parameters.get_child (pid_param);
a_parameters.get_child (uid_param, 1);
a_parameters.get_child (gid_param, 2);
- a_parameters.get_child (options_param, 3);
+
+ RequestInfo request;
int pid = pid_param.get ();
- int uid = uid_param.get ();
- int gid = gid_param.get ();
- std::vector<Glib::ustring> options (options_param.get ());
- for (std::vector<Glib::ustring>::iterator iter = options.begin ();
- iter != options.end ();
- ++iter) {
- if (*iter != "--output") {
- continue;
- }
-
- Gio::DBus::Error error
- (Gio::DBus::Error::INVALID_ARGS,
- _("--output parameter is "
- "forbidden for security reasons"));
- a_invocation->return_error (error);
- }
-
- SafePtr<char, DefaultRef, FreeUnref> filepath (tempnam(0, 0));
- THROW_IF_FAIL (filepath);
+ request.uid = uid_param.get ();
+ request.gid = gid_param.get ();
+
+ THROW_IF_FAIL (!request_map.count (pid));
std::vector<UString> argv;
- argv.push_back ("perf");
- argv.push_back ("record");
argv.push_back ("--pid");
argv.push_back (UString::compose ("%1", pid));
- argv.push_back ("--output");
- argv.push_back (filepath.get ());
- argv.insert (argv.end (), options.begin (), options.end ());
-
- std::cout << "Launching perf with pid: " << pid << std::endl;
-
- bool is_launched =
- common::launch_program (argv,
- perf_pid,
- master_pty_fd,
- perf_stdout_fd,
- perf_stderr_fd);
-
- THROW_IF_FAIL (is_launched);
-
- std::cout << "Perf started" << std::endl;
-
- Glib::RefPtr<Glib::MainContext> context =
- Glib::MainContext::get_default ();
- context->signal_idle ().connect
- (sigc::bind<int, int,
- Glib::RefPtr<Gio::DBus::MethodInvocation>,
- Glib::ustring>
- (sigc::mem_fun (*this,
- &PerfServer::Priv::on_wait_for_record_to_exit),
- uid, gid,
- a_invocation,
- filepath.get ()));
+
+ request_map[pid] = request;
+ PerfRecordOptions options;
+
+ THROW_IF_FAIL (request.profiler);
+ request.profiler->record (argv, options);
+
+ Glib::Variant<unsigned> perf_data =
+ Glib::Variant<unsigned>::create (next_request_id++);
+
+ Glib::VariantContainerBase response;
+ response = Glib::VariantContainerBase::create_tuple (perf_data);
+ a_invocation->return_value (response);
+ }
+ else if (a_request_name == "RecordDoneSignal") {
+ Glib::Variant<unsigned> request_param;
+ a_parameters.get_child (request_param);
+
+ unsigned request_id = request_param.get ();
+ THROW_IF_FAIL (request_map.count (request_id));
+ request_map[request_id].invocation = a_invocation;
+ request_map[request_id].profiler->record_done_signal ().connect
+ (sigc::bind<unsigned> (sigc::mem_fun
+ (*this, &PerfServer::Priv::on_record_done_signal),
+ request_id));
}
else if (a_request_name == "DetachFromProcess") {
- kill (perf_pid, SIGINT);
+ Glib::Variant<unsigned> request_param;
+ a_parameters.get_child (request_param);
+
+ unsigned request_id = request_param.get ();
+ THROW_IF_FAIL (request_map.count (request_id));
+
+ THROW_IF_FAIL (request_map[request_id].profiler);
+ request_map[request_id].profiler->stop_recording ();
Glib::VariantContainerBase response;
a_invocation->return_value (response);
@@ -238,6 +249,28 @@ struct PerfServer::Priv {
}
void
+ on_record_done_signal (const UString &a_report, unsigned a_request_id)
+ {
+ NEMIVER_TRY;
+
+ THROW_IF_FAIL (request_map.count (a_request_id));
+
+ Glib::Variant<Glib::ustring> perf_data =
+ Glib::Variant<Glib::ustring>::create (a_report);
+
+ Glib::VariantContainerBase response =
+ Glib::VariantContainerBase::create_tuple (perf_data);
+
+ chown (a_report.c_str (),
+ request_map[a_request_id].uid,
+ request_map[a_request_id].gid);
+
+ request_map[a_request_id].invocation->return_value (response);
+
+ NEMIVER_CATCH_NOX;
+ }
+
+ void
init ()
{
introspection_data = Gio::DBus::NodeInfo::create_for_xml
@@ -253,7 +286,7 @@ struct PerfServer::Priv {
void
on_bus_acquired (const Glib::RefPtr<Gio::DBus::Connection> &a_connection,
- const Glib::ustring&)
+ const Glib::ustring&)
{
NEMIVER_TRY;
diff --git a/src/profengine/nmv-record-options.h b/src/profengine/nmv-record-options.h
new file mode 100644
index 0000000..d089ad8
--- /dev/null
+++ b/src/profengine/nmv-record-options.h
@@ -0,0 +1,57 @@
+//Author: Fabien Parent
+/*
+ *This file is part of the Nemiver project
+ *
+ *Nemiver is free software; you can redistribute
+ *it and/or modify it under the terms of
+ *the GNU General Public License as published by the
+ *Free Software Foundation; either version 2,
+ *or (at your option) any later version.
+ *
+ *Nemiver is distributed in the hope that it will
+ *be useful, but WITHOUT ANY WARRANTY;
+ *without even the implied warranty of
+ *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *See the GNU General Public License for more details.
+ *
+ *You should have received a copy of the
+ *GNU General Public License along with Nemiver;
+ *see the file COPYING.
+ *If not, write to the Free Software Foundation,
+ *Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ *See COPYRIGHT file copyright information.
+ */
+#ifndef __NMV_RECORD_OPTIONS_H__
+#define __NMV_RECORD_OPTIONS_H__
+
+#include "common/nmv-namespace.h"
+
+NEMIVER_BEGIN_NAMESPACE (nemiver)
+
+class RecordOptions {
+ RecordOptions (const RecordOptions&);
+ RecordOptions& operator= (const RecordOptions&);
+
+protected:
+ RecordOptions ()
+ {
+ }
+
+public:
+ virtual ~RecordOptions ()
+ {
+ }
+
+ virtual bool do_callgraph_recording () const = 0;
+ virtual bool do_collect_without_buffering () const = 0;
+ virtual bool do_collect_raw_sample_records () const = 0;
+ virtual bool do_system_wide_collection () const = 0;
+ virtual bool do_sample_addresses () const = 0;
+ virtual bool do_sample_timestamps () const = 0;
+}; // end namespace RecordOptions
+
+NEMIVER_END_NAMESPACE (nemiver)
+
+#endif /* __NMV_RECORD_OPTIONS_H__ */
+
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]