mirror of
https://github.com/varun-r-mallya/sysprof.git
synced 2026-02-11 23:51:06 +00:00
Add support for software fallback counters
This commit is contained in:
42
collector.c
42
collector.c
@ -27,6 +27,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <sys/ioctl.h>
|
#include <sys/ioctl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#include "stackstash.h"
|
#include "stackstash.h"
|
||||||
#include "collector.h"
|
#include "collector.h"
|
||||||
@ -41,6 +42,8 @@
|
|||||||
|
|
||||||
#define N_PAGES 32 /* Number of pages in the ringbuffer */
|
#define N_PAGES 32 /* Number of pages in the ringbuffer */
|
||||||
|
|
||||||
|
#define N_WAKEUP_EVENTS 150
|
||||||
|
|
||||||
typedef struct counter_t counter_t;
|
typedef struct counter_t counter_t;
|
||||||
typedef struct sample_event_t sample_event_t;
|
typedef struct sample_event_t sample_event_t;
|
||||||
typedef struct mmap_event_t mmap_event_t;
|
typedef struct mmap_event_t mmap_event_t;
|
||||||
@ -126,6 +129,7 @@ struct Collector
|
|||||||
tracker_t * tracker;
|
tracker_t * tracker;
|
||||||
GTimeVal latest_reset;
|
GTimeVal latest_reset;
|
||||||
|
|
||||||
|
int prev_samples;
|
||||||
int n_samples;
|
int n_samples;
|
||||||
|
|
||||||
GList * counters;
|
GList * counters;
|
||||||
@ -211,10 +215,8 @@ on_read (gpointer data)
|
|||||||
gboolean skip_samples;
|
gboolean skip_samples;
|
||||||
Collector *collector;
|
Collector *collector;
|
||||||
uint64_t head, tail;
|
uint64_t head, tail;
|
||||||
gboolean first;
|
|
||||||
|
|
||||||
collector = counter->collector;
|
collector = counter->collector;
|
||||||
first = collector->n_samples == 0;
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
int n_bytes = mask + 1;
|
int n_bytes = mask + 1;
|
||||||
@ -241,6 +243,10 @@ on_read (gpointer data)
|
|||||||
|
|
||||||
skip_samples = in_dead_period (collector);
|
skip_samples = in_dead_period (collector);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
g_print ("n bytes %d\n", head - tail);
|
||||||
|
#endif
|
||||||
|
|
||||||
while (head - tail >= sizeof (struct perf_event_header))
|
while (head - tail >= sizeof (struct perf_event_header))
|
||||||
{
|
{
|
||||||
struct perf_event_header *header = (void *)(counter->data + (tail & mask));
|
struct perf_event_header *header = (void *)(counter->data + (tail & mask));
|
||||||
@ -269,7 +275,16 @@ on_read (gpointer data)
|
|||||||
counter->mmap_page->data_tail = tail;
|
counter->mmap_page->data_tail = tail;
|
||||||
|
|
||||||
if (collector->callback)
|
if (collector->callback)
|
||||||
collector->callback (first, collector->data);
|
{
|
||||||
|
if (collector->n_samples - collector->prev_samples >= N_WAKEUP_EVENTS)
|
||||||
|
{
|
||||||
|
gboolean first_sample = collector->prev_samples == 0;
|
||||||
|
|
||||||
|
collector->callback (first_sample, collector->data);
|
||||||
|
|
||||||
|
collector->prev_samples = collector->n_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: return proper errors */
|
/* FIXME: return proper errors */
|
||||||
@ -333,14 +348,24 @@ counter_new (Collector *collector,
|
|||||||
* FIXME: consider using frequency instead
|
* FIXME: consider using frequency instead
|
||||||
*/
|
*/
|
||||||
attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_CALLCHAIN;
|
attr.sample_type = PERF_SAMPLE_IP | PERF_SAMPLE_TID | PERF_SAMPLE_CALLCHAIN;
|
||||||
attr.wakeup_events = 100000;
|
attr.wakeup_events = N_WAKEUP_EVENTS;
|
||||||
attr.disabled = TRUE;
|
attr.disabled = TRUE;
|
||||||
|
|
||||||
attr.mmap = 1;
|
attr.mmap = 1;
|
||||||
attr.comm = 1;
|
attr.comm = 1;
|
||||||
attr.task = 1;
|
attr.task = 1;
|
||||||
|
|
||||||
fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0);
|
if ((fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0)) < 0)
|
||||||
|
{
|
||||||
|
if (errno == ENODEV)
|
||||||
|
{
|
||||||
|
attr.type = PERF_TYPE_SOFTWARE;
|
||||||
|
attr.config = PERF_COUNT_SW_CPU_CLOCK;
|
||||||
|
attr.sample_period = 10000000;
|
||||||
|
|
||||||
|
fd = sysprof_perf_counter_open (&attr, -1, cpu, -1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
{
|
{
|
||||||
@ -452,6 +477,7 @@ collector_reset (Collector *collector)
|
|||||||
}
|
}
|
||||||
|
|
||||||
collector->n_samples = 0;
|
collector->n_samples = 0;
|
||||||
|
collector->prev_samples = 0;
|
||||||
|
|
||||||
g_get_current_time (&collector->latest_reset);
|
g_get_current_time (&collector->latest_reset);
|
||||||
|
|
||||||
@ -589,6 +615,7 @@ process_event (Collector *collector,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_EVENT_LOST:
|
case PERF_EVENT_LOST:
|
||||||
|
g_print ("lost event\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_EVENT_COMM:
|
case PERF_EVENT_COMM:
|
||||||
@ -600,9 +627,11 @@ process_event (Collector *collector,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_EVENT_THROTTLE:
|
case PERF_EVENT_THROTTLE:
|
||||||
|
g_print ("throttle\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_EVENT_UNTHROTTLE:
|
case PERF_EVENT_UNTHROTTLE:
|
||||||
|
g_print ("unthrottle\n");
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PERF_EVENT_FORK:
|
case PERF_EVENT_FORK:
|
||||||
@ -617,7 +646,8 @@ process_event (Collector *collector,
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
g_warning ("unknown event: %d (%d)\n", event->header.type, event->header.size);
|
g_warning ("unknown event: %d (%d)\n",
|
||||||
|
event->header.type, event->header.size);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user