From 791fff95c3acf11bddad67bcbcf641c22f39f5e2 Mon Sep 17 00:00:00 2001 From: Damien Lespiau Date: Fri, 21 Jan 2011 11:01:24 +0000 Subject: [PATCH] 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. --- collector.c | 8 +++++--- collector.h | 1 + sysprof-cli.c | 27 +++++++++++++++++++++++---- sysprof.c | 2 +- 4 files changed, 30 insertions(+), 8 deletions(-) diff --git a/collector.c b/collector.c index 86d96ed0..b28964fd 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 3c0c1181..2689a597 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 90f5b13e..e8d26ee2 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 55f1b09b..20d3d2c4 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);