Merge branch 'drm-next-4.2' of git://people.freedesktop.org/~agd5f/linux
[firefly-linux-kernel-4.4.55.git] / tools / perf / util / stat.c
1 #include <math.h>
2 #include "stat.h"
3 #include "evsel.h"
4
5 void update_stats(struct stats *stats, u64 val)
6 {
7         double delta;
8
9         stats->n++;
10         delta = val - stats->mean;
11         stats->mean += delta / stats->n;
12         stats->M2 += delta*(val - stats->mean);
13
14         if (val > stats->max)
15                 stats->max = val;
16
17         if (val < stats->min)
18                 stats->min = val;
19 }
20
21 double avg_stats(struct stats *stats)
22 {
23         return stats->mean;
24 }
25
26 /*
27  * http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance
28  *
29  *       (\Sum n_i^2) - ((\Sum n_i)^2)/n
30  * s^2 = -------------------------------
31  *                  n - 1
32  *
33  * http://en.wikipedia.org/wiki/Stddev
34  *
35  * The std dev of the mean is related to the std dev by:
36  *
37  *             s
38  * s_mean = -------
39  *          sqrt(n)
40  *
41  */
42 double stddev_stats(struct stats *stats)
43 {
44         double variance, variance_mean;
45
46         if (stats->n < 2)
47                 return 0.0;
48
49         variance = stats->M2 / (stats->n - 1);
50         variance_mean = variance / stats->n;
51
52         return sqrt(variance_mean);
53 }
54
55 double rel_stddev_stats(double stddev, double avg)
56 {
57         double pct = 0.0;
58
59         if (avg)
60                 pct = 100.0 * stddev/avg;
61
62         return pct;
63 }
64
65 bool __perf_evsel_stat__is(struct perf_evsel *evsel,
66                            enum perf_stat_evsel_id id)
67 {
68         struct perf_stat *ps = evsel->priv;
69
70         return ps->id == id;
71 }
72
73 #define ID(id, name) [PERF_STAT_EVSEL_ID__##id] = #name
74 static const char *id_str[PERF_STAT_EVSEL_ID__MAX] = {
75         ID(NONE,                x),
76         ID(CYCLES_IN_TX,        cpu/cycles-t/),
77         ID(TRANSACTION_START,   cpu/tx-start/),
78         ID(ELISION_START,       cpu/el-start/),
79         ID(CYCLES_IN_TX_CP,     cpu/cycles-ct/),
80 };
81 #undef ID
82
83 void perf_stat_evsel_id_init(struct perf_evsel *evsel)
84 {
85         struct perf_stat *ps = evsel->priv;
86         int i;
87
88         /* ps->id is 0 hence PERF_STAT_EVSEL_ID__NONE by default */
89
90         for (i = 0; i < PERF_STAT_EVSEL_ID__MAX; i++) {
91                 if (!strcmp(perf_evsel__name(evsel), id_str[i])) {
92                         ps->id = i;
93                         break;
94                 }
95         }
96 }
97
98 struct perf_counts *perf_counts__new(int ncpus)
99 {
100         int size = sizeof(struct perf_counts) +
101                    ncpus * sizeof(struct perf_counts_values);
102
103         return zalloc(size);
104 }
105
106 void perf_counts__delete(struct perf_counts *counts)
107 {
108         free(counts);
109 }
110
111 static void perf_counts__reset(struct perf_counts *counts, int ncpus)
112 {
113         memset(counts, 0, (sizeof(*counts) +
114                (ncpus * sizeof(struct perf_counts_values))));
115 }
116
117 void perf_evsel__reset_counts(struct perf_evsel *evsel, int ncpus)
118 {
119         perf_counts__reset(evsel->counts, ncpus);
120 }
121
122 int perf_evsel__alloc_counts(struct perf_evsel *evsel, int ncpus)
123 {
124         evsel->counts = perf_counts__new(ncpus);
125         return evsel->counts != NULL ? 0 : -ENOMEM;
126 }
127
128 void perf_evsel__free_counts(struct perf_evsel *evsel)
129 {
130         perf_counts__delete(evsel->counts);
131         evsel->counts = NULL;
132 }