Blame stats.h

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