mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-09 14:40:54 +00:00
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.
This commit is contained in:
74
collector.c
74
collector.c
@ -379,9 +379,30 @@ map_buffer (counter_t *counter, GError **err)
|
|||||||
return address;
|
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 *
|
static counter_t *
|
||||||
counter_new (Collector *collector,
|
counter_new (Collector *collector,
|
||||||
int cpu,
|
int cpu,
|
||||||
|
counter_t *output,
|
||||||
GError **err)
|
GError **err)
|
||||||
{
|
{
|
||||||
struct perf_counter_attr attr;
|
struct perf_counter_attr attr;
|
||||||
@ -420,37 +441,32 @@ counter_new (Collector *collector,
|
|||||||
|
|
||||||
counter->collector = collector;
|
counter->collector = collector;
|
||||||
counter->fd = fd;
|
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;
|
counter->cpu = cpu;
|
||||||
|
|
||||||
fd_add_watch (fd, counter);
|
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);
|
||||||
|
|
||||||
fd_set_read_callback (fd, on_read);
|
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;
|
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
|
static void
|
||||||
counter_free (counter_t *counter)
|
counter_free (counter_t *counter)
|
||||||
{
|
{
|
||||||
@ -705,13 +721,15 @@ collector_start (Collector *collector,
|
|||||||
{
|
{
|
||||||
int n_cpus = get_n_cpus ();
|
int n_cpus = get_n_cpus ();
|
||||||
int i;
|
int i;
|
||||||
|
counter_t *output;
|
||||||
|
|
||||||
if (!collector->tracker)
|
if (!collector->tracker)
|
||||||
collector->tracker = tracker_new ();
|
collector->tracker = tracker_new ();
|
||||||
|
|
||||||
|
output = NULL;
|
||||||
for (i = 0; i < n_cpus; ++i)
|
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)
|
if (!counter)
|
||||||
{
|
{
|
||||||
@ -726,6 +744,9 @@ collector_start (Collector *collector,
|
|||||||
}
|
}
|
||||||
|
|
||||||
collector->counters = g_list_append (collector->counters, counter);
|
collector->counters = g_list_append (collector->counters, counter);
|
||||||
|
|
||||||
|
if (!output)
|
||||||
|
output = counter;
|
||||||
}
|
}
|
||||||
|
|
||||||
enable_counters (collector);
|
enable_counters (collector);
|
||||||
@ -746,7 +767,8 @@ collector_stop (Collector *collector)
|
|||||||
{
|
{
|
||||||
counter_t *counter = list->data;
|
counter_t *counter = list->data;
|
||||||
|
|
||||||
on_read (counter);
|
if (counter->data)
|
||||||
|
on_read (counter);
|
||||||
|
|
||||||
counter_free (counter);
|
counter_free (counter);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -216,6 +216,7 @@ struct perf_counter_attr {
|
|||||||
#define PERF_COUNTER_IOC_REFRESH _IO ('$', 2)
|
#define PERF_COUNTER_IOC_REFRESH _IO ('$', 2)
|
||||||
#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
|
#define PERF_COUNTER_IOC_RESET _IO ('$', 3)
|
||||||
#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
|
#define PERF_COUNTER_IOC_PERIOD _IOW('$', 4, u64)
|
||||||
|
#define PERF_COUNTER_IOC_SET_OUTPUT _IO ('$', 5)
|
||||||
|
|
||||||
enum perf_counter_ioc_flags {
|
enum perf_counter_ioc_flags {
|
||||||
PERF_IOC_FLAG_GROUP = 1U << 0,
|
PERF_IOC_FLAG_GROUP = 1U << 0,
|
||||||
|
|||||||
Reference in New Issue
Block a user