1*1a3d31e3SAndroid Build Coastguard Worker /*
2*1a3d31e3SAndroid Build Coastguard Worker * Copyright IBM Corp. 2008
3*1a3d31e3SAndroid Build Coastguard Worker *
4*1a3d31e3SAndroid Build Coastguard Worker * Author(s): Martin Peschke <[email protected]>
5*1a3d31e3SAndroid Build Coastguard Worker * Stefan Raspl <[email protected]>
6*1a3d31e3SAndroid Build Coastguard Worker *
7*1a3d31e3SAndroid Build Coastguard Worker * This program is free software; you can redistribute it and/or modify
8*1a3d31e3SAndroid Build Coastguard Worker * it under the terms of the GNU General Public License as published by
9*1a3d31e3SAndroid Build Coastguard Worker * the Free Software Foundation; either version 2 of the License, or
10*1a3d31e3SAndroid Build Coastguard Worker * (at your option) any later version.
11*1a3d31e3SAndroid Build Coastguard Worker *
12*1a3d31e3SAndroid Build Coastguard Worker * This program is distributed in the hope that it will be useful,
13*1a3d31e3SAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
14*1a3d31e3SAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15*1a3d31e3SAndroid Build Coastguard Worker * GNU General Public License for more details.
16*1a3d31e3SAndroid Build Coastguard Worker *
17*1a3d31e3SAndroid Build Coastguard Worker * You should have received a copy of the GNU General Public License
18*1a3d31e3SAndroid Build Coastguard Worker * along with this program; if not, write to the Free Software
19*1a3d31e3SAndroid Build Coastguard Worker * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20*1a3d31e3SAndroid Build Coastguard Worker */
21*1a3d31e3SAndroid Build Coastguard Worker
22*1a3d31e3SAndroid Build Coastguard Worker #ifndef STATS_H
23*1a3d31e3SAndroid Build Coastguard Worker #define STATS_H
24*1a3d31e3SAndroid Build Coastguard Worker
25*1a3d31e3SAndroid Build Coastguard Worker #include <linux/types.h>
26*1a3d31e3SAndroid Build Coastguard Worker #include "blktrace.h"
27*1a3d31e3SAndroid Build Coastguard Worker
28*1a3d31e3SAndroid Build Coastguard Worker struct minmax {
29*1a3d31e3SAndroid Build Coastguard Worker __u64 min;
30*1a3d31e3SAndroid Build Coastguard Worker __u64 max;
31*1a3d31e3SAndroid Build Coastguard Worker __u64 sum;
32*1a3d31e3SAndroid Build Coastguard Worker __u64 sos;
33*1a3d31e3SAndroid Build Coastguard Worker __u64 num;
34*1a3d31e3SAndroid Build Coastguard Worker };
35*1a3d31e3SAndroid Build Coastguard Worker
minmax_init(struct minmax * mm)36*1a3d31e3SAndroid Build Coastguard Worker static inline void minmax_init(struct minmax *mm)
37*1a3d31e3SAndroid Build Coastguard Worker {
38*1a3d31e3SAndroid Build Coastguard Worker mm->min = -1ULL;
39*1a3d31e3SAndroid Build Coastguard Worker mm->max = 0;
40*1a3d31e3SAndroid Build Coastguard Worker mm->sum = 0;
41*1a3d31e3SAndroid Build Coastguard Worker mm->sos = 0;
42*1a3d31e3SAndroid Build Coastguard Worker mm->num = 0;
43*1a3d31e3SAndroid Build Coastguard Worker }
44*1a3d31e3SAndroid Build Coastguard Worker
minmax_account(struct minmax * mm,__u64 value)45*1a3d31e3SAndroid Build Coastguard Worker static inline void minmax_account(struct minmax *mm, __u64 value)
46*1a3d31e3SAndroid Build Coastguard Worker {
47*1a3d31e3SAndroid Build Coastguard Worker mm->sum += value;
48*1a3d31e3SAndroid Build Coastguard Worker mm->sos += value * value;
49*1a3d31e3SAndroid Build Coastguard Worker if (value < mm->min)
50*1a3d31e3SAndroid Build Coastguard Worker mm->min = value;
51*1a3d31e3SAndroid Build Coastguard Worker if (value > mm->max)
52*1a3d31e3SAndroid Build Coastguard Worker mm->max = value;
53*1a3d31e3SAndroid Build Coastguard Worker mm->num++;
54*1a3d31e3SAndroid Build Coastguard Worker }
55*1a3d31e3SAndroid Build Coastguard Worker
minmax_merge(struct minmax * dst,struct minmax * src)56*1a3d31e3SAndroid Build Coastguard Worker static inline void minmax_merge(struct minmax *dst, struct minmax *src)
57*1a3d31e3SAndroid Build Coastguard Worker {
58*1a3d31e3SAndroid Build Coastguard Worker dst->sum += src->sum;
59*1a3d31e3SAndroid Build Coastguard Worker dst->sos += src->sos;
60*1a3d31e3SAndroid Build Coastguard Worker if (src->min < dst->min)
61*1a3d31e3SAndroid Build Coastguard Worker dst->min = src->min;
62*1a3d31e3SAndroid Build Coastguard Worker if (src->max > dst->max)
63*1a3d31e3SAndroid Build Coastguard Worker dst->max = src->max;
64*1a3d31e3SAndroid Build Coastguard Worker dst->num += src->num;
65*1a3d31e3SAndroid Build Coastguard Worker }
66*1a3d31e3SAndroid Build Coastguard Worker
minmax_to_be(struct minmax * mm)67*1a3d31e3SAndroid Build Coastguard Worker static inline void minmax_to_be(struct minmax *mm)
68*1a3d31e3SAndroid Build Coastguard Worker {
69*1a3d31e3SAndroid Build Coastguard Worker mm->sum = cpu_to_be64(mm->sum);
70*1a3d31e3SAndroid Build Coastguard Worker mm->sos = cpu_to_be64(mm->sos);
71*1a3d31e3SAndroid Build Coastguard Worker mm->min = cpu_to_be64(mm->min);
72*1a3d31e3SAndroid Build Coastguard Worker mm->max = cpu_to_be64(mm->max);
73*1a3d31e3SAndroid Build Coastguard Worker mm->num = cpu_to_be64(mm->num);
74*1a3d31e3SAndroid Build Coastguard Worker }
75*1a3d31e3SAndroid Build Coastguard Worker
minmax_avg(struct minmax * mm)76*1a3d31e3SAndroid Build Coastguard Worker static inline double minmax_avg(struct minmax *mm)
77*1a3d31e3SAndroid Build Coastguard Worker {
78*1a3d31e3SAndroid Build Coastguard Worker if (!mm->num)
79*1a3d31e3SAndroid Build Coastguard Worker return 0;
80*1a3d31e3SAndroid Build Coastguard Worker
81*1a3d31e3SAndroid Build Coastguard Worker return (mm->sum / (double)mm->num);
82*1a3d31e3SAndroid Build Coastguard Worker }
83*1a3d31e3SAndroid Build Coastguard Worker
minmax_var(struct minmax * mm)84*1a3d31e3SAndroid Build Coastguard Worker static inline double minmax_var(struct minmax *mm)
85*1a3d31e3SAndroid Build Coastguard Worker {
86*1a3d31e3SAndroid Build Coastguard Worker double num = (double)mm->num;
87*1a3d31e3SAndroid Build Coastguard Worker
88*1a3d31e3SAndroid Build Coastguard Worker if (!mm->num)
89*1a3d31e3SAndroid Build Coastguard Worker return 0;
90*1a3d31e3SAndroid Build Coastguard Worker
91*1a3d31e3SAndroid Build Coastguard Worker return ((mm->sos - ((mm->sum * mm->sum) / num)) / num);
92*1a3d31e3SAndroid Build Coastguard Worker }
93*1a3d31e3SAndroid Build Coastguard Worker
minmax_print(FILE * fp,const char * s,struct minmax * mm)94*1a3d31e3SAndroid Build Coastguard Worker static inline int minmax_print(FILE *fp, const char *s, struct minmax *mm)
95*1a3d31e3SAndroid Build Coastguard Worker {
96*1a3d31e3SAndroid Build Coastguard Worker return fprintf(fp, "%s: num %Ld, min %Ld, max %Ld, sum %Ld, squ %Ld, "
97*1a3d31e3SAndroid Build Coastguard Worker "avg %.1f, var %.1f\n", s, (unsigned long long)mm->num,
98*1a3d31e3SAndroid Build Coastguard Worker (unsigned long long)mm->min, (unsigned long long)mm->max,
99*1a3d31e3SAndroid Build Coastguard Worker (unsigned long long)mm->sum, (unsigned long long)mm->sos,
100*1a3d31e3SAndroid Build Coastguard Worker minmax_avg(mm), minmax_var(mm));
101*1a3d31e3SAndroid Build Coastguard Worker }
102*1a3d31e3SAndroid Build Coastguard Worker
103*1a3d31e3SAndroid Build Coastguard Worker struct histlog2 {
104*1a3d31e3SAndroid Build Coastguard Worker int first;
105*1a3d31e3SAndroid Build Coastguard Worker int delta;
106*1a3d31e3SAndroid Build Coastguard Worker int num;
107*1a3d31e3SAndroid Build Coastguard Worker };
108*1a3d31e3SAndroid Build Coastguard Worker
histlog2_upper_limit(int index,struct histlog2 * h)109*1a3d31e3SAndroid Build Coastguard Worker static inline __u64 histlog2_upper_limit(int index, struct histlog2 *h)
110*1a3d31e3SAndroid Build Coastguard Worker {
111*1a3d31e3SAndroid Build Coastguard Worker return h->first + (index ? h->delta << (index - 1) : 0);
112*1a3d31e3SAndroid Build Coastguard Worker }
113*1a3d31e3SAndroid Build Coastguard Worker
histlog2_index(__u64 val,struct histlog2 * h)114*1a3d31e3SAndroid Build Coastguard Worker static inline int histlog2_index(__u64 val, struct histlog2 *h)
115*1a3d31e3SAndroid Build Coastguard Worker {
116*1a3d31e3SAndroid Build Coastguard Worker int i;
117*1a3d31e3SAndroid Build Coastguard Worker
118*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++);
119*1a3d31e3SAndroid Build Coastguard Worker return i;
120*1a3d31e3SAndroid Build Coastguard Worker }
121*1a3d31e3SAndroid Build Coastguard Worker
histlog2_account(__u32 * bucket,__u32 val,struct histlog2 * h)122*1a3d31e3SAndroid Build Coastguard Worker static inline void histlog2_account(__u32 *bucket, __u32 val,
123*1a3d31e3SAndroid Build Coastguard Worker struct histlog2 *h)
124*1a3d31e3SAndroid Build Coastguard Worker {
125*1a3d31e3SAndroid Build Coastguard Worker int index = histlog2_index(val, h);
126*1a3d31e3SAndroid Build Coastguard Worker bucket[index]++;
127*1a3d31e3SAndroid Build Coastguard Worker }
128*1a3d31e3SAndroid Build Coastguard Worker
histlog2_merge(struct histlog2 * h,__u32 * dst,__u32 * src)129*1a3d31e3SAndroid Build Coastguard Worker static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src)
130*1a3d31e3SAndroid Build Coastguard Worker {
131*1a3d31e3SAndroid Build Coastguard Worker int i;
132*1a3d31e3SAndroid Build Coastguard Worker
133*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < h->num; i++)
134*1a3d31e3SAndroid Build Coastguard Worker dst[i] += src[i];
135*1a3d31e3SAndroid Build Coastguard Worker }
136*1a3d31e3SAndroid Build Coastguard Worker
histlog2_to_be(__u32 a[],struct histlog2 * h)137*1a3d31e3SAndroid Build Coastguard Worker static inline void histlog2_to_be(__u32 a[], struct histlog2 *h)
138*1a3d31e3SAndroid Build Coastguard Worker {
139*1a3d31e3SAndroid Build Coastguard Worker int i;
140*1a3d31e3SAndroid Build Coastguard Worker
141*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < h->num; i++)
142*1a3d31e3SAndroid Build Coastguard Worker a[i] = cpu_to_be32(a[i]);
143*1a3d31e3SAndroid Build Coastguard Worker }
144*1a3d31e3SAndroid Build Coastguard Worker
histlog2_print(FILE * fp,const char * s,__u32 a[],struct histlog2 * h)145*1a3d31e3SAndroid Build Coastguard Worker static inline void histlog2_print(FILE *fp, const char *s, __u32 a[],
146*1a3d31e3SAndroid Build Coastguard Worker struct histlog2 *h)
147*1a3d31e3SAndroid Build Coastguard Worker {
148*1a3d31e3SAndroid Build Coastguard Worker int i;
149*1a3d31e3SAndroid Build Coastguard Worker
150*1a3d31e3SAndroid Build Coastguard Worker fprintf(fp, "%s:\n", s);
151*1a3d31e3SAndroid Build Coastguard Worker for (i = 0; i < h->num - 1; i++) {
152*1a3d31e3SAndroid Build Coastguard Worker fprintf(fp, " %10ld:%6d",
153*1a3d31e3SAndroid Build Coastguard Worker (unsigned long)(histlog2_upper_limit(i, h)), a[i]);
154*1a3d31e3SAndroid Build Coastguard Worker if (!((i + 1) % 4))
155*1a3d31e3SAndroid Build Coastguard Worker fprintf(fp, "\n");
156*1a3d31e3SAndroid Build Coastguard Worker }
157*1a3d31e3SAndroid Build Coastguard Worker fprintf(fp, " >%8ld:%6d\n",
158*1a3d31e3SAndroid Build Coastguard Worker (unsigned long)(histlog2_upper_limit(i - 1, h)), a[i]);
159*1a3d31e3SAndroid Build Coastguard Worker }
160*1a3d31e3SAndroid Build Coastguard Worker
161*1a3d31e3SAndroid Build Coastguard Worker #endif
162