diff options
Diffstat (limited to 'stats.h')
-rw-r--r-- | stats.h | 155 |
1 files changed, 155 insertions, 0 deletions
@@ -0,0 +1,155 @@ +/* + * Copyright IBM Corp. 2008 + * + * Author(s): Martin Peschke <mp3@de.ibm.com> + * Stefan Raspl <stefan.raspl@de.ibm.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef STATS_H +#define STATS_H + +#include <linux/types.h> +#include "blktrace.h" + +struct minmax { + __u64 min; + __u64 max; + __u64 sum; + __u64 sos; + __u64 num; +}; + +static inline void minmax_init(struct minmax *mm) +{ + mm->min = -1ULL; + mm->max = 0; + mm->sum = 0; + mm->sos = 0; + mm->num = 0; +} + +static inline void minmax_account(struct minmax *mm, __u64 value) +{ + mm->sum += value; + mm->sos += value * value; + if (value < mm->min) + mm->min = value; + if (value > mm->max) + mm->max = value; + mm->num++; +} + +static inline void minmax_merge(struct minmax *dst, struct minmax *src) +{ + dst->sum += src->sum; + dst->sos += src->sos; + if (src->min < dst->min) + dst->min = src->min; + if (src->max > dst->max) + dst->max = src->max; + dst->num += src->num; +} + +static inline void minmax_to_be(struct minmax *mm) +{ + mm->sum = cpu_to_be64(mm->sum); + mm->sos = cpu_to_be64(mm->sos); + mm->min = cpu_to_be64(mm->min); + mm->max = cpu_to_be64(mm->max); + mm->num = cpu_to_be64(mm->num); +} + +static inline double minmax_avg(struct minmax *mm) +{ + return (mm->sum / (double)mm->num); +} + +static inline double minmax_var(struct minmax *mm) +{ + double num = (double)mm->num; + + return ((mm->sos - ((mm->sum * mm->sum) / num)) / num); +} + +static inline int minmax_print(FILE *fp, const char *s, struct minmax *mm) +{ + return fprintf(fp, "%s: num %Ld, min %Ld, max %Ld, sum %Ld, squ %Ld, " + "avg %.1f, var %.1f\n", s, (unsigned long long)mm->num, + (unsigned long long)mm->min, (unsigned long long)mm->max, + (unsigned long long)mm->sum, (unsigned long long)mm->sos, + minmax_avg(mm), minmax_var(mm)); +} + +struct histlog2 { + int first; + int delta; + int num; +}; + +static inline __u64 histlog2_upper_limit(int index, struct histlog2 *h) +{ + return h->first + (index ? h->delta << (index - 1) : 0); +} + +static inline int histlog2_index(__u64 val, struct histlog2 *h) +{ + int i; + + for (i = 0; i < (h->num - 1) && val > histlog2_upper_limit(i, h); i++); + return i; +} + +static inline void histlog2_account(__u32 *bucket, __u32 val, + struct histlog2 *h) +{ + int index = histlog2_index(val, h); + bucket[index]++; +} + +static inline void histlog2_merge(struct histlog2 *h, __u32 *dst, __u32 *src) +{ + int i; + + for (i = 0; i < h->num; i++) + dst[i] += src[i]; +} + +static inline void histlog2_to_be(__u32 a[], struct histlog2 *h) +{ + int i; + + for (i = 0; i < h->num; i++) + a[i] = cpu_to_be32(a[i]); +} + +static inline void histlog2_print(FILE *fp, const char *s, __u32 a[], + struct histlog2 *h) +{ + int i; + + fprintf(fp, "%s:\n", s); + for (i = 0; i < h->num - 1; i++) { + fprintf(fp, " %10ld:%6d", + (unsigned long)(histlog2_upper_limit(i, h)), a[i]); + if (!((i + 1) % 4)) + fprintf(fp, "\n"); + } + fprintf(fp, " >%8ld:%6d\n", + (unsigned long)(histlog2_upper_limit(i - 1, h)), a[i]); +} + +#endif |