summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Lespiau <damien.lespiau@intel.com>2011-01-21 11:01:24 +0000
committerSøren Sandmann Pedersen <sandmann@daimi.au.dk>2011-01-27 17:07:07 -0500
commit791fff95c3acf11bddad67bcbcf641c22f39f5e2 (patch)
tree46411ec330604aee033b96710f05b08686ea5ae1
parente14788c87e44ae66915e942e279e8b32850b87fd (diff)
cli: Allow to get samples from single pid
perf lets you decide to only get events that concerns a single process and thus make sysprof profile this process instead of the whole system (it can happen that you don't really care about other processes that are just then noise). As a side effect, this allows sysprof to not run as root if you have the rights on the process you want to profile.
-rw-r--r--collector.c8
-rw-r--r--collector.h1
-rw-r--r--sysprof-cli.c27
-rw-r--r--sysprof.c2
4 files changed, 30 insertions, 8 deletions
diff --git a/collector.c b/collector.c
index 86d96ed..b28964f 100644
--- a/collector.c
+++ b/collector.c
@@ -401,6 +401,7 @@ counter_disable (counter_t *counter)
static counter_t *
counter_new (Collector *collector,
+ pid_t pid,
int cpu,
counter_t *output,
GError **err)
@@ -427,13 +428,13 @@ counter_new (Collector *collector,
attr.task = 1;
attr.exclude_idle = 1;
- if (!collector->use_hw_counters || (fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0)) < 0)
+ if (!collector->use_hw_counters || (fd = sysprof_perf_counter_open (&attr, pid, cpu, -1, 0)) < 0)
{
attr.type = PERF_TYPE_SOFTWARE;
attr.config = PERF_COUNT_SW_CPU_CLOCK;
attr.sample_period = 1000000;
- fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0);
+ fd = sysprof_perf_counter_open (&attr, pid, cpu, -1, 0);
}
if (fd < 0)
@@ -717,6 +718,7 @@ process_event (Collector *collector,
gboolean
collector_start (Collector *collector,
+ pid_t pid,
GError **err)
{
int n_cpus = get_n_cpus ();
@@ -729,7 +731,7 @@ collector_start (Collector *collector,
output = NULL;
for (i = 0; i < n_cpus; ++i)
{
- counter_t *counter = counter_new (collector, i, output, err);
+ counter_t *counter = counter_new (collector, pid, i, output, err);
if (!counter)
{
diff --git a/collector.h b/collector.h
index 3c0c118..2689a59 100644
--- a/collector.h
+++ b/collector.h
@@ -38,6 +38,7 @@ Collector *collector_new (gboolean use_hw_counters,
CollectorFunc callback,
gpointer data);
gboolean collector_start (Collector *collector,
+ pid_t pid,
GError **err);
void collector_stop (Collector *collector);
void collector_reset (Collector *collector);
diff --git a/sysprof-cli.c b/sysprof-cli.c
index 90f5b13..e8d26ee 100644
--- a/sysprof-cli.c
+++ b/sysprof-cli.c
@@ -111,19 +111,38 @@ die (const char *err_msg)
exit (-1);
}
+static int opt_pid = -1;
+
+static GOptionEntry entries[] =
+{
+ { "pid", 'p', 0, G_OPTION_ARG_INT, &opt_pid,
+ "Make sysprof specific to a task", NULL },
+ { NULL }
+};
+
int
main (int argc, char *argv[])
{
- Application *app = g_new0 (Application, 1);
+ Application *app;
+ GOptionContext *context;
GError *err;
+ err = NULL;
+
+ context = g_option_context_new ("- Sysprof");
+ g_option_context_add_main_entries (context, entries, NULL);
+ if (!g_option_context_parse (context, &argc, &argv, &err))
+ {
+ g_print ("Failed to parse options: %s\n", err->message);
+ return 1;
+ }
+
+ app = g_new0 (Application, 1);
app->collector = collector_new (FALSE, NULL, NULL);
app->outfile = g_strdup (argv[1]);
app->main_loop = g_main_loop_new (NULL, 0);
- err = NULL;
-
- if (!collector_start (app->collector, &err))
+ if (!collector_start (app->collector, (pid_t) opt_pid, &err))
die (err->message);
if (argc < 2)
diff --git a/sysprof.c b/sysprof.c
index 55f1b09..20d3d2c 100644
--- a/sysprof.c
+++ b/sysprof.c
@@ -365,7 +365,7 @@ on_start_toggled (GtkWidget *widget, gpointer data)
return;
}
- if (collector_start (app->collector, &err))
+ if (collector_start (app->collector, -1, &err))
{
delete_data (app);