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