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.
This commit is contained in:
Damien Lespiau
2011-01-21 11:01:24 +00:00
committed by Søren Sandmann Pedersen
parent e14788c87e
commit 791fff95c3
4 changed files with 30 additions and 8 deletions

View File

@ -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)
{

View File

@ -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);

View File

@ -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)

View File

@ -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);