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 | { | |
78 | return (mm->sum / (double)mm->num); | |
79 | } | |
80 | ||
81 | static inline double minmax_var(struct minmax *mm) | |
82 | { | |
83 | double num = (double)mm->num; | |
84 | ||
85 | return ((mm->sos - ((mm->sum * mm->sum) / num)) / num); | |
86 | } | |
87 | ||
88 | static inline int minmax_print(FILE *fp, const char *s, struct minmax *mm) | |
89 | { | |
90 | return fprintf(fp, "%s: num %Ld, min %Ld, max %Ld, sum %Ld, squ %Ld, " | |
91 | "avg %.1f, var %.1f\n", s, (unsigned long long)mm->num, | |
92 | (unsigned long long)mm->min, (unsigned long long)mm->max, | |
93 | (unsigned long long)mm->sum, (unsigned long long)mm->sos, | |
94 | minmax_avg(mm), minmax_var(mm)); | |
95 | } | |
96 | ||
97 | struct histlog2 { | |
98 | int first; | |
99 | int delta; | |
100 | int num; | |
101 | }; | |
102 | ||
103 | static inline __u64 histlog2_upper_limit(int index, struct histlog2 *h) | |
104 | { | |
105 | return h->first + (index ? h->delta << (index - 1) : 0); | |
106 | } | |
107 | ||
108 | static inline int histlog2_index(__u64 val, struct histlog2 *h) | |
109 | { | |
110 | int i; | |
111 | ||
112 | for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++); | |
113 | return i; | |
114 | } | |
115 | ||
116 | static inline void histlog2_account(__u32 *bucket, __u32 val, | |
117 | struct histlog2 *h) | |
118 | { | |
119 | int index = histlog2_index(val, h); | |
120 | bucket[index]++; | |
121 | } | |
122 | ||
123 | static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src) | |
124 | { | |
125 | int i; | |
126 | ||
b5f8804a | 127 | for (i = 0; i < h->num; i++) |
cc19ddd6 MP |
128 | dst[i] += src[i]; |
129 | } | |
130 | ||
131 | static inline void histlog2_to_be(__u32 a[], struct histlog2 *h) | |
132 | { | |
133 | int i; | |
134 | ||
b5f8804a | 135 | for (i = 0; i < h->num; i++) |
cc19ddd6 MP |
136 | a[i] = cpu_to_be32(a[i]); |
137 | } | |
138 | ||
139 | static inline void histlog2_print(FILE *fp, const char *s, __u32 a[], | |
140 | struct histlog2 *h) | |
141 | { | |
142 | int i; | |
143 | ||
144 | fprintf(fp, "%s:\n", s); | |
145 | for (i = 0; i < h->num - 1; i++) { | |
146 | fprintf(fp, " %10ld:%6d", | |
147 | (unsigned long)(histlog2_upper_limit(i, h)), a[i]); | |
148 | if (!((i + 1) % 4)) | |
149 | fprintf(fp, "\n"); | |
150 | } | |
151 | fprintf(fp, " >%8ld:%6d\n", | |
152 | (unsigned long)(histlog2_upper_limit(i - 1, h)), a[i]); | |
153 | } | |
154 | ||
155 | #endif |