[sysprof] Use the SET_OUTPUT ioctl to direct all output to the same buffer
- From: Søren Sandmann Pedersen <ssp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [sysprof] Use the SET_OUTPUT ioctl to direct all output to the same buffer
- Date: Sat, 24 Apr 2010 14:48:39 +0000 (UTC)
commit c960ebd52fee06becf1b943a4a4eeae566a35a81
Author: Søren Sandmann Pedersen <sandmann daimi au dk>
Date: Sat Apr 24 10:49:18 2010 -0400
Use the SET_OUTPUT ioctl to direct all output to the same buffer
This ensures that we don't get events out of order, which will make
the profiles look a lot less bogus on multi-core systems.
collector.c | 82 +++++++++++++++++++++++++++++++++++--------------------
perf_counter.h | 1 +
2 files changed, 53 insertions(+), 30 deletions(-)
---
diff --git a/collector.c b/collector.c
index 2bba702..86d96ed 100644
--- a/collector.c
+++ b/collector.c
@@ -379,9 +379,30 @@ map_buffer (counter_t *counter, GError **err)
return address;
}
+static gboolean
+counter_set_output (counter_t *counter, int output)
+{
+ return ioctl (counter->fd, PERF_COUNTER_IOC_SET_OUTPUT, output) == 0;
+}
+
+static void
+counter_enable (counter_t *counter)
+{
+ ioctl (counter->fd, PERF_COUNTER_IOC_ENABLE);
+}
+
+static void
+counter_disable (counter_t *counter)
+{
+ d_print ("disable\n");
+
+ ioctl (counter->fd, PERF_COUNTER_IOC_DISABLE);
+}
+
static counter_t *
counter_new (Collector *collector,
int cpu,
+ counter_t *output,
GError **err)
{
struct perf_counter_attr attr;
@@ -417,41 +438,36 @@ counter_new (Collector *collector,
if (fd < 0)
return fail (err, "Could not open performance counter");
-
+
counter->collector = collector;
counter->fd = fd;
-
- counter->mmap_page = map_buffer (counter, err);
-
- if (!counter->mmap_page || counter->mmap_page == MAP_FAILED)
- return NULL;
-
- counter->data = (uint8_t *)counter->mmap_page + get_page_size ();
- counter->tail = 0;
counter->cpu = cpu;
-
- fd_add_watch (fd, counter);
- fd_set_read_callback (fd, on_read);
+ if (output && counter_set_output (counter, output->fd))
+ {
+ counter->mmap_page = NULL;
+ counter->data = NULL;
+ counter->tail = 0;
+ }
+ else
+ {
+ counter->mmap_page = map_buffer (counter, err);
+
+ if (!counter->mmap_page || counter->mmap_page == MAP_FAILED)
+ return NULL;
+
+ counter->data = (uint8_t *)counter->mmap_page + get_page_size ();
+ counter->tail = 0;
+
+ fd_add_watch (fd, counter);
+
+ fd_set_read_callback (fd, on_read);
+ }
return counter;
}
static void
-counter_enable (counter_t *counter)
-{
- ioctl (counter->fd, PERF_COUNTER_IOC_ENABLE);
-}
-
-static void
-counter_disable (counter_t *counter)
-{
- d_print ("disable\n");
-
- ioctl (counter->fd, PERF_COUNTER_IOC_DISABLE);
-}
-
-static void
counter_free (counter_t *counter)
{
d_print ("munmap\n");
@@ -705,13 +721,15 @@ collector_start (Collector *collector,
{
int n_cpus = get_n_cpus ();
int i;
+ counter_t *output;
if (!collector->tracker)
collector->tracker = tracker_new ();
-
+
+ output = NULL;
for (i = 0; i < n_cpus; ++i)
{
- counter_t *counter = counter_new (collector, i, err);
+ counter_t *counter = counter_new (collector, i, output, err);
if (!counter)
{
@@ -724,8 +742,11 @@ collector_start (Collector *collector,
return FALSE;
}
-
+
collector->counters = g_list_append (collector->counters, counter);
+
+ if (!output)
+ output = counter;
}
enable_counters (collector);
@@ -746,7 +767,8 @@ collector_stop (Collector *collector)
{
counter_t *counter = list->data;
- on_read (counter);
+ if (counter->data)
+ on_read (counter);
counter_free (counter);
}
diff --git a/perf_counter.h b/perf_counter.h
index 4d3ad31..a22d2cb 100644
--- a/perf_counter.h
+++ b/perf_counter.h
@@ -216,6 +216,7 @@ struct perf_counter_attr {
#define PERF_COUNTER_IOC_REFRESH _IO ('$', 2)
#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
+#define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5)
enum perf_counter_ioc_flags {
PERF_IOC_FLAG_GROUP = 1U << 0,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]