diff options
author | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2010-04-24 10:49:18 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <sandmann@daimi.au.dk> | 2010-04-24 10:50:26 -0400 |
commit | c960ebd52fee06becf1b943a4a4eeae566a35a81 (patch) | |
tree | d26eb137985d96bb2257b04e62086ade0223d1fe | |
parent | 539c3a87546f6a3baf8bd33b1633c1dc07f66496 (diff) |
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.
-rw-r--r-- | collector.c | 82 | ||||
-rw-r--r-- | 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, |