Commit | Line | Data |
---|---|---|
cc19ddd6 MP |
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> | |
8d388c8e | 26 | #include "blktrace.h" |
cc19ddd6 MP |
27 | |
28 | struct minmax { | |
29 | __u64 min; | |
30 | __u64 max; | |
31 | __u64 sum; | |
32 | __u64 sos; | |
33 | __u64 num; | |
34 | }; | |
35 | ||
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 | ||
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 | ||
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 | ||
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 | ||
76 | static inline double minmax_avg(struct minmax *mm) | |
77 | { | |
b7e74b00 TM |
78 | if (!mm->num) |
79 | return 0; | |
80 | ||
cc19ddd6 MP |
81 | return (mm->sum / (double)mm->num); |
82 | } | |
83 | ||
84 | static inline double minmax_var(struct minmax *mm) | |
85 | { | |
86 | double num = (double)mm->num; | |
87 | ||
b7e74b00 TM |
88 | if (!mm->num) |
89 | return 0; | |
90 | ||
cc19ddd6 MP |
91 | return ((mm->sos - ((mm->sum * mm->sum) / num)) / num); |
92 | } | |
93 | ||
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 | ||
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 | ||
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 | ||
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 | ||
129 | static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src) | |
130 | { | |
131 | int i; | |
132 | ||
b5f8804a | 133 | for (i = 0; i < h->num; i++) |
cc19ddd6 MP |
134 | dst[i] += src[i]; |
135 | } | |
136 | ||
137 | static inline void histlog2_to_be(__u32 a[], struct histlog2 *h) | |
138 | { | |
139 | int i; | |
140 | ||
b5f8804a | 141 | for (i = 0; i < h->num; i++) |
cc19ddd6 MP |
142 | a[i] = cpu_to_be32(a[i]); |
143 | } | |
144 | ||
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 |