Home | History | Annotate | Download | only in blktrace
      1 /*
      2  * Copyright IBM Corp. 2008
      3  *
      4  * Author(s): Martin Peschke <mp3 (at) de.ibm.com>
      5  *            Stefan Raspl <stefan.raspl (at) 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 
     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 	if (!mm->num)
     79 		return 0;
     80 
     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 
     88 	if (!mm->num)
     89 		return 0;
     90 
     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 
    133 	for (i = 0; i < h->num; i++)
    134 		dst[i] += src[i];
    135 }
    136 
    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 
    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