1e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat/*
2e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * blktrace output analysis: generate a timeline & gather statistics
3e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
4e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.com>
5e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
6e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is free software; you can redistribute it and/or modify
7e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  it under the terms of the GNU General Public License as published by
8e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  the Free Software Foundation; either version 2 of the License, or
9e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  (at your option) any later version.
10e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
11e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  This program is distributed in the hope that it will be useful,
12e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  GNU General Public License for more details.
15e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
16e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  You should have received a copy of the GNU General Public License
17e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  along with this program; if not, write to the Free Software
18e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat *
20e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat */
21e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include <stdio.h>
22e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#include "globals.h"
23e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
24e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehattypedef struct avg_info *ai_dip_t;
25e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2q_dm_avg(struct d_info *dip) { return &dip->avgs.q2q_dm; }
26e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2a_dm_avg(struct d_info *dip) { return &dip->avgs.q2a_dm; }
27e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2c_dm_avg(struct d_info *dip) { return &dip->avgs.q2c_dm; }
28e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
29e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2q_avg(struct d_info *dip) { return &dip->avgs.q2q; }
30e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2c_avg(struct d_info *dip) { return &dip->avgs.q2c; }
31e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2a_avg(struct d_info *dip) { return &dip->avgs.q2a; }
32e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2g_avg(struct d_info *dip) { return &dip->avgs.q2g; }
33e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_s2g_avg(struct d_info *dip) { return &dip->avgs.s2g; }
34e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_g2i_avg(struct d_info *dip) { return &dip->avgs.g2i; }
35e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_q2m_avg(struct d_info *dip) { return &dip->avgs.q2m; }
36e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_i2d_avg(struct d_info *dip) { return &dip->avgs.i2d; }
37e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_dip_t dip_d2c_avg(struct d_info *dip) { return &dip->avgs.d2c; }
38e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
39e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehattypedef struct avg_info *ai_pip_t;
40e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2q_dm_avg(struct p_info *pip) { return &pip->avgs.q2q_dm; }
41e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2a_dm_avg(struct p_info *pip) { return &pip->avgs.q2a_dm; }
42e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2c_dm_avg(struct p_info *pip) { return &pip->avgs.q2c_dm; }
43e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
44e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2q_avg(struct p_info *pip) { return &pip->avgs.q2q; }
45e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2c_avg(struct p_info *pip) { return &pip->avgs.q2c; }
46e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2a_avg(struct p_info *pip) { return &pip->avgs.q2a; }
47e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2g_avg(struct p_info *pip) { return &pip->avgs.q2g; }
48e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_s2g_avg(struct p_info *pip) { return &pip->avgs.s2g; }
49e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_g2i_avg(struct p_info *pip) { return &pip->avgs.g2i; }
50e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_q2m_avg(struct p_info *pip) { return &pip->avgs.q2m; }
51e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_i2d_avg(struct p_info *pip) { return &pip->avgs.i2d; }
52e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatai_pip_t pip_d2c_avg(struct p_info *pip) { return &pip->avgs.d2c; }
53e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
54e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_section_hdr(FILE *ofp, char *hdr)
55e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
56e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "==================== ");
57e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%s", hdr);
58e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, " ====================\n\n");
59e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
60e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
61e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_hdr(FILE *ofp, char *hdr)
62e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
63e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%15s %13s %13s %13s %11s\n",
64e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	        hdr, "MIN", "AVG", "MAX", "N" );
65e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "--------------- ------------- ------------- ------------- -----------\n");
66e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
67e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
68e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_avg(FILE *ofp, char *hdr, struct avg_info *ap, int do_easy)
69e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
70e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (ap->n > 0) {
71e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ap->avg = BIT_TIME(ap->total) / (double)ap->n;
72e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%-15s %13.9f %13.9f %13.9f %11d\n", hdr,
73e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			BIT_TIME(ap->min), ap->avg, BIT_TIME(ap->max), ap->n);
74e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
75e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (do_easy && easy_parse_avgs) {
76e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(xavgs_ofp,
77e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"%s %.9lf %.9lf %.9lf %d\n",
78e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				hdr, BIT_TIME(ap->min), ap->avg,
79e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat						BIT_TIME(ap->max), ap->n);
80e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
81e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
82e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
83e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
84e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline char *avg2string(struct avg_info *ap, char *string)
85e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
86e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (ap->n > 0)
87e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		sprintf(string, "%13.9f", ap->avg);
88e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	else
89e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		sprintf(string, " ");
90e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return string;
91e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
92e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
93e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __oda {
94e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
95e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ai_dip_t (*func)(struct d_info *);
96e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
97e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dip_avg(struct d_info *dip, void *arg)
98e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
99e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __oda *odap = arg;
100e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ai_dip_t ap = odap->func(dip);
101e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (ap->n > 0) {
102e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char dev_info[15];
103e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ap->avg = BIT_TIME(ap->total) / (double)ap->n;
104e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__output_avg(odap->ofp, make_dev_hdr(dev_info, 15, dip, 1),
105e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				ap, 0);
106e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
107e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
108e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
109e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_dip_avg(FILE *ofp, char *hdr, ai_dip_t (*func)(struct d_info *))
110e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
111e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __oda oda = { .ofp = ofp, .func = func};
112e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_hdr(ofp, hdr);
113e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dip_avg, &oda);
114e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
115e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
116e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
117e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __q2d {
118e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
119e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	void *q2d_all;
120e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int n;
121e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
122e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_q2d_histo(struct d_info *dip, void *arg)
123e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
124e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __q2d *q2dp = arg;
125e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
126e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (q2d_ok(dip->q2d_priv)) {
127e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char dev_info[15];
128e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		FILE *ofp = q2dp->ofp;
129e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
130e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(q2dp->ofp, "%10s | ",
131e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat					make_dev_hdr(dev_info, 15, dip, 1));
132e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		q2d_display(ofp, dip->q2d_priv);
133e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		q2d_acc(q2dp->q2d_all, dip->q2d_priv);
134e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		q2dp->n++;
135e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
136e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
137e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
138e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_q2d_histo(FILE *ofp)
139e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
140e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __q2d __q2d = {
141e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.ofp = ofp,
142e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.q2d_all = q2d_alloc(),
143e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		.n = 0
144e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	};
145e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
146e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | ", "DEV");
147e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q2d_display_header(ofp);
148e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "--------- | ");
149e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q2d_display_dashes(ofp);
150e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_q2d_histo, &__q2d);
151e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
152e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (__q2d.n) {
153e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "========== | ");
154e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		q2d_display_dashes(ofp);
155e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | ", "AVG");
156e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		q2d_display(ofp, __q2d.q2d_all);
157e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "\n");
158e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
159e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
160e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q2d_free(__q2d.q2d_all);
161e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
162e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
163e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint n_merges = 0;
164e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct {
165e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	unsigned long long nq, nd, blkmin, blkmax, total;
166e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} merge_data;
167e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dip_merge_ratio(struct d_info *dip, void *arg)
168e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
169e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double blks_avg;
170e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char dev_info[15];
171e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double ratio, q2c_n, d2c_n;
172e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
173e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->n_qs == 0 || dip->n_ds == 0)
174e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return;
175e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	else if (dip->n_qs < dip->n_ds)
176e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		dip->n_qs = dip->n_ds;
177e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
178e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q2c_n = dip->n_qs;
179e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	d2c_n = dip->n_ds;
180e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (q2c_n > 0.0 && d2c_n > 0.0) {
181e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (q2c_n < d2c_n)
182e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			ratio = 1.0;
183e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		else
184e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			ratio = q2c_n / d2c_n;
185e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		blks_avg = (double)dip->avgs.blks.total / d2c_n;
186e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf((FILE *)arg,
187e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"%10s | %8llu %8llu %7.1lf | %8llu %8llu %8llu %8llu\n",
188e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 1),
189e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)dip->n_qs,
190e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)dip->n_ds,
191e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			ratio,
192e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)dip->avgs.blks.min,
193e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)blks_avg,
194e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)dip->avgs.blks.max,
195e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(unsigned long long)dip->avgs.blks.total);
196e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
197e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (easy_parse_avgs) {
198e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(xavgs_ofp,
199e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"DMI %s %llu %llu %.9lf %llu %llu %llu %llu\n",
200e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				make_dev_hdr(dev_info, 15, dip, 0),
201e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)dip->n_qs,
202e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)dip->n_ds,
203e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				ratio,
204e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)dip->avgs.blks.min,
205e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)blks_avg,
206e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)dip->avgs.blks.max,
207e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				(unsigned long long)dip->avgs.blks.total);
208e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
209e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
210e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (n_merges++ == 0) {
211e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmin = dip->avgs.blks.min;
212e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmax = dip->avgs.blks.max;
213e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
214e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
215e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		merge_data.nq += dip->n_qs;
216e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		merge_data.nd += dip->n_ds;
217e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		merge_data.total += dip->avgs.blks.total;
218e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (dip->avgs.blks.min < merge_data.blkmin)
219e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmin = dip->avgs.blks.min;
220e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (dip->avgs.blks.max > merge_data.blkmax)
221e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmax = dip->avgs.blks.max;
222e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
223e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
224e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
225e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_dip_merge_ratio(FILE *ofp)
226e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
227e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %8s %8s %7s | %8s %8s %8s %8s\n", "DEV", "#Q", "#D", "Ratio", "BLKmin", "BLKavg", "BLKmax", "Total");
228e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | -------- -------- ------- | -------- -------- -------- --------\n");
229e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dip_merge_ratio, ofp);
230e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_merges > 1) {
231e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "---------- | -------- -------- ------- | -------- -------- -------- --------\n");
232e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | %8s %8s %7s | %8s %8s %8s %8s\n", "DEV", "#Q", "#D", "Ratio", "BLKmin", "BLKavg", "BLKmax", "Total");
233e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf((FILE *)ofp,
234e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"%10s | %8llu %8llu %7.1lf | %8llu %8llu %8llu %8llu\n",
235e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"TOTAL", merge_data.nq, merge_data.nd,
236e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			(float)merge_data.nq / (float)merge_data.nd,
237e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmin,
238e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.total / merge_data.nd,
239e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			merge_data.blkmax, merge_data.total);
240e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
241e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
242e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
243e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
244e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __ohead_data {
245e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__u64 total;
246e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int n;
247e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
248e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
249e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct ohead_data {
250e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
251e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __ohead_data q2g, g2i, q2m, i2d, d2c, q2c;
252e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
253e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
254e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define __update_odp(odp, dip, fld)					\
255e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	do {								\
256e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(odp)-> fld .total += dip->avgs. fld . total;		\
257e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(odp)-> fld .n     += dip->avgs. fld . n;		\
258e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	} while (0)
259e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
260e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dip_prep_ohead(struct d_info *dip, void *arg)
261e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
262e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->avgs.q2c.n > 0 && dip->avgs.q2c.total > 0) {
263e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char dev_info[15];
264e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		struct ohead_data *odp = arg;
265e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		double q2c_total = (double)(dip->avgs.q2c.total);
266e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
267e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(odp->ofp,
268e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"%10s | %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%%\n",
269e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 1),
270e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			100.0 * (double)(dip->avgs.q2g.total) / q2c_total,
271e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			100.0 * (double)(dip->avgs.g2i.total) / q2c_total,
272e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			100.0 * (double)(dip->avgs.q2m.total) / q2c_total,
273e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			100.0 * (double)(dip->avgs.i2d.total) / q2c_total,
274e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			100.0 * (double)(dip->avgs.d2c.total) / q2c_total);
275e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
276e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, q2g);
277e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, g2i);
278e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, q2m);
279e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, i2d);
280e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, d2c);
281e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__update_odp(odp, dip, q2c);
282e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
283e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
284e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
285e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat#define OD_AVG(od, fld, q2c)						\
286e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	(od. fld .n == 0) ? (double)0.0 :				\
287e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(100.0 * ((double)((od). fld . total) / q2c))
288e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
289e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_dip_prep_ohead(FILE *ofp)
290e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
291e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double q2c;
292e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct ohead_data od;
293e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
294e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	memset(&od, 0, sizeof(od));
295e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	od.ofp = ofp;
296e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
297e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %9s %9s %9s %9s %9s\n",
298e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"DEV", "Q2G", "G2I", "Q2M", "I2D", "D2C");
299e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | --------- --------- --------- --------- ---------\n");
300e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dip_prep_ohead, &od);
301e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
302e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (od.q2g.n == 0 && od.g2i.n == 0 && od.q2m.n == 0 &&
303e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat						od.i2d.n == 0 && od.d2c.n == 0)
304e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		goto out;
305e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
306e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	q2c = od.q2c.total;
307e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | --------- --------- --------- --------- ---------\n");
308e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%% %8.4lf%%\n", "Overall",
309e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			OD_AVG(od, q2g, q2c), OD_AVG(od, g2i, q2c),
310e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			OD_AVG(od, q2m, q2c), OD_AVG(od, i2d, q2c),
311e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			OD_AVG(od, d2c, q2c));
312e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
313e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatout:
314e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
315e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
316e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
317e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct seek_mode_info {
318e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct seek_mode_info *next;
319e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long long mode;
320e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int nseeks;
321e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
322e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct o_seek_info {
323e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long long nseeks, median;
324e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double mean;
325e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct seek_mode_info *head;
326e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} seek_info;
327e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint n_seeks;
328e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
329e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_seek_mode_info(FILE *ofp, struct o_seek_info *sip)
330e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
331e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct seek_mode_info *p, *this, *new_list = NULL;
332e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
333e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	while ((this = sip->head) != NULL) {
334e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		sip->head = this->next;
335e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		this->next = NULL;
336e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
337e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (new_list == NULL || this->nseeks > new_list->nseeks)
338e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			new_list = this;
339e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		else if (this->nseeks == new_list->nseeks) {
340e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			for (p = new_list; p != NULL; p = p->next)
341e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				if (p->mode == this->mode)
342e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat					break;
343e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
344e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			if (p)
345e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				this->nseeks += p->nseeks;
346e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			else
347e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				this->next = new_list;
348e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			new_list = this;
349e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
350e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
351e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
352e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %15lld %15.1lf %15lld | %lld(%d)",
353e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	        "Average", sip->nseeks, sip->mean / sip->nseeks,
354e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		sip->median / sip->nseeks, new_list->mode, new_list->nseeks);
355e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
356e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (new_list->next) {
357e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		int i = 0;
358e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		for (p = new_list->next; p != NULL; p = p->next)
359e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			i++;
360e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "\n%10s   %15s %15s %15s   ...(%d more)\n", "", "", "", "", i);
361e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
362e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
363e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
364e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid add_seek_mode_info(struct o_seek_info *sip, struct mode *mp)
365e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
366e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int i;
367e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long long *lp = mp->modes;
368e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct seek_mode_info *smip;
369e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
370e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	n_seeks++;
371e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	for (i = 0; i < mp->nmds; i++, lp++) {
372e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		for (smip = sip->head; smip; smip = smip->next) {
373e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			if (smip->mode == *lp) {
374e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				smip->nseeks += mp->most_seeks;
375e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				break;
376e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			}
377e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
378e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (!smip) {
379e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			struct seek_mode_info *new = malloc(sizeof(*new));
380e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
381e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			new->next = sip->head;
382e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			sip->head = new;
383e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			new->mode = *lp;
384e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			new->nseeks = mp->most_seeks;
385e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
386e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			add_buf(new);
387e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
388e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
389e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
390e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
391e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic void do_output_dip_seek_info(struct d_info *dip, FILE *ofp, int is_q2q)
392e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
393e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double mean;
394e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int i, nmodes;
395e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long long nseeks;
396e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char dev_info[15];
397e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long long median;
398e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct mode m;
399e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	void *handle = is_q2q ? dip->q2q_handle : dip->seek_handle;
400e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
401e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	nseeks = seeki_nseeks(handle);
402e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (nseeks > 0) {
403e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		mean = seeki_mean(handle);
404e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		median = seeki_median(handle);
405e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		nmodes = seeki_mode(handle, &m);
406e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
407e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | %15lld %15.1lf %15lld | %lld(%d)",
408e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 1), nseeks, mean,
409e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			median, nmodes > 0 ? m.modes[0] : 0, m.most_seeks);
410e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (nmodes > 2)
411e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(ofp, "\n%10s   %15s %15s %15s   ...(%d more)\n", "", "", "", "", nmodes-1);
412e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		else  {
413e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			for (i = 1; i < nmodes; i++)
414e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				fprintf(ofp, " %lld", m.modes[i]);
415e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(ofp, "\n");
416e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
417e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
418e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (easy_parse_avgs) {
419e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			char *rec = is_q2q ? "QSK" : "DSK";
420e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(xavgs_ofp,
421e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"%s %s %lld %.9lf %lld %lld %d",
422e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				rec, make_dev_hdr(dev_info, 15, dip, 0),
423e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				nseeks, mean, median,
424e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				nmodes > 0 ? m.modes[0] : 0, m.most_seeks);
425e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				for (i = 1; i < nmodes; i++)
426e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat					fprintf(xavgs_ofp, " %lld", m.modes[i]);
427e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				fprintf(xavgs_ofp, "\n");
428e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
429e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
430e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		seek_info.nseeks += nseeks;
431e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		seek_info.mean += (nseeks * mean);
432e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		seek_info.median += (nseeks * median);
433e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		add_seek_mode_info(&seek_info, &m);
434e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		free(m.modes);
435e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
436e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
437e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
438e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dip_seek_info(struct d_info *dip, void *arg)
439e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
440e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	do_output_dip_seek_info(dip, (FILE *)arg, 0);
441e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
442e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
443e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dip_q2q_seek_info(struct d_info *dip, void *arg)
444e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
445e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	do_output_dip_seek_info(dip, (FILE *)arg, 1);
446e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
447e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
448e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_dip_seek_info(FILE *ofp)
449e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
450e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	n_seeks = 1;
451e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	memset(&seek_info, 0, sizeof(seek_info));
452e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
453e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %15s %15s %15s | %-15s\n", "DEV", "NSEEKS",
454e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"MEAN", "MEDIAN", "MODE");
455e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | --------------- --------------- --------------- | ---------------\n");
456e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dip_seek_info, ofp);
457e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_seeks > 1) {
458e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "---------- | --------------- --------------- --------------- | ---------------\n");
459e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | %15s %15s %15s | %-15s\n",
460e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		        "Overall", "NSEEKS", "MEAN", "MEDIAN", "MODE");
461e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_seek_mode_info(ofp, &seek_info);
462e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "\n");
463e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
464e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
465e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
466e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
467e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_dip_q2q_seek_info(FILE *ofp)
468e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
469e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	n_seeks = 1;
470e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	memset(&seek_info, 0, sizeof(seek_info));
471e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
472e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %15s %15s %15s | %-15s\n", "DEV", "NSEEKS",
473e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"MEAN", "MEDIAN", "MODE");
474e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | --------------- --------------- --------------- | ---------------\n");
475e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dip_q2q_seek_info, ofp);
476e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_seeks > 1) {
477e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "---------- | --------------- --------------- --------------- | ---------------\n");
478e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | %15s %15s %15s | %-15s\n",
479e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		        "Overall", "NSEEKS", "MEAN", "MEDIAN", "MODE");
480e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_seek_mode_info(ofp, &seek_info);
481e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "\n");
482e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
483e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
484e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
485e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
486e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __opa {
487e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
488e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ai_pip_t (*func)(struct p_info *);
489e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
490e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
491e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_pip_avg(struct p_info *pip, void *arg)
492e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
493e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __opa *opap = arg;
494e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ai_pip_t ap = opap->func(pip);
495e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
496e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (ap->n > 0) {
497e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char proc_name[15];
498e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		snprintf(proc_name, 15, "%s", pip->name);
499e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
500e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ap->avg = BIT_TIME(ap->total) / (double)ap->n;
501e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__output_avg(opap->ofp, proc_name, ap, 0);
502e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
503e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
504e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
505e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_pip_avg(FILE *ofp, char *hdr, ai_pip_t (*func)(struct p_info *))
506e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
507e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __opa opa = { .ofp = ofp, .func = func };
508e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
509e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_hdr(ofp, hdr);
510e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	pip_foreach_out(__output_pip_avg, &opa);
511e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
512e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
513e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
514e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint n_plugs;
515e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct plug_info {
516e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	long n_plugs, n_unplugs_t;
517e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double t_percent;
518e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} plug_info;
519e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
520e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_plug(struct d_info *dip, void *arg)
521e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
522e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char dev_info[15];
523e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp = arg;
524e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double delta, pct;
525e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
526e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->is_plugged)
527e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		dip_unplug(dip->device, dip->end_time, 0);
528e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if ((dip->nplugs + dip->nplugs_t) > 0) {
529e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		delta = dip->end_time - dip->start_time;
530e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		pct = 100.0 * (dip->plugged_time / delta);
531e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
532e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%10s | %10d(%10d) | %13.9lf%%\n",
533e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 1),
534e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			dip->nplugs, dip->nplugs_t, pct);
535e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
536e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (easy_parse_avgs) {
537e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(xavgs_ofp,
538e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"PLG %s %d %d %.9lf\n",
539e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				make_dev_hdr(dev_info, 15, dip, 0),
540e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				dip->nplugs, dip->nplugs_t, pct);
541e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
542e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
543e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		n_plugs++;
544e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		plug_info.n_plugs += dip->nplugs;
545e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		plug_info.n_unplugs_t += dip->nplugs_t;
546e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		plug_info.t_percent += pct;
547e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
548e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
549e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
550e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_plug_all(FILE *ofp, struct plug_info *p)
551e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
552e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | ---------- ----------  | ----------------\n");
553e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10s %10s  | %s\n",
554e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	        "Overall", "# Plugs", "# Timer Us", "% Time Q Plugged");
555e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10ld(%10ld) | %13.9lf%%\n", "Average",
556e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	        p->n_plugs / n_plugs, p->n_unplugs_t / n_plugs,
557e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		p->t_percent / n_plugs);
558e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
559e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
560e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
561e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat__u64 n_nios_uplugs, n_nios_uplugs_t;
562e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct nios_plug_info {
563e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__u64 tot_nios_up, tot_nios_up_t;
564e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} nios_plug_info;
565e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
566e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_plug_nios(struct d_info *dip, void *arg)
567e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
568e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char dev_info[15];
569e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp = arg;
570e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double a_nios_uplug = 0.0, a_nios_uplug_t = 0.0;
571e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
572e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->nios_up && dip->nplugs) {
573e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		a_nios_uplug = (double)dip->nios_up / (double)dip->nplugs;
574e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		n_nios_uplugs += dip->nplugs;
575e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		nios_plug_info.tot_nios_up += dip->nios_up;
576e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
577e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->nios_upt && dip->nplugs_t) {
578e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		a_nios_uplug_t = (double)dip->nios_upt / (double)dip->nplugs_t;
579e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		n_nios_uplugs_t += dip->nplugs_t;
580e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		nios_plug_info.tot_nios_up_t += dip->nios_upt;
581e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
582e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
583e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10.1lf   %10.1lf\n",
584e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		make_dev_hdr(dev_info, 15, dip, 1),
585e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		a_nios_uplug, a_nios_uplug_t);
586e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
587e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (easy_parse_avgs) {
588e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(xavgs_ofp,
589e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			"UPG %s %.9lf %.9lf\n",
590e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 0),
591e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			a_nios_uplug, a_nios_uplug_t);
592e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
593e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
594e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
595e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_uplug_all(FILE *ofp, struct nios_plug_info *p)
596e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
597e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	double ios_unp = 0.0, ios_unp_to = 0.0;
598e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
599e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_nios_uplugs)
600e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ios_unp = (double)p->tot_nios_up / (double)n_nios_uplugs;
601e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_nios_uplugs_t)
602e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		ios_unp_to = (double)p->tot_nios_up_t / (double)n_nios_uplugs_t;
603e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
604e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | ----------   ----------\n");
605e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10s   %10s\n",
606e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		"Overall", "IOs/Unp", "IOs/Unp(to)");
607e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10.1lf   %10.1lf\n",
608e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		"Average", ios_unp, ios_unp_to);
609e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
610e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
611e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_plug_info(FILE *ofp)
612e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
613e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10s %10s  | %s\n",
614e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	        "DEV", "# Plugs", "# Timer Us", "% Time Q Plugged");
615e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | ---------- ----------  | ----------------\n");
616e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__dip_output_plug, ofp);
617e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_plugs > 1)
618e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__dip_output_plug_all(ofp, &plug_info);
619e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
620e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
621e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %10s   %10s\n",
622e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		"DEV", "IOs/Unp", "IOs/Unp(to)");
623e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | ----------   ----------\n");
624e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__dip_output_plug_nios, ofp);
625e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_nios_uplugs || n_nios_uplugs_t)
626e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__dip_output_uplug_all(ofp, &nios_plug_info);
627e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
628e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
629e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
630e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint n_actQs;
631e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct actQ_info {
632e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__u64 t_qs;
633e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__u64 t_act_qs;
634e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat} actQ_info;
635e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
636e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_actQ(struct d_info *dip, void *arg)
637e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
638e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (dip->n_qs > 0 && !remapper_dev(dip->device)) {
639e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		char dev_info[15];
640e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		double a_actQs = (double)dip->t_act_q / (double)dip->n_qs;
641e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
642e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf((FILE *)arg, "%10s | %13.1lf\n",
643e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			make_dev_hdr(dev_info, 15, dip, 1), a_actQs);
644e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
645e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (easy_parse_avgs) {
646e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(xavgs_ofp,
647e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				"ARQ %s %.9lf\n",
648e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat				make_dev_hdr(dev_info, 15, dip, 0), a_actQs);
649e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
650e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
651e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		n_actQs++;
652e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		actQ_info.t_qs += dip->n_qs;
653e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		actQ_info.t_act_qs += dip->t_act_q;
654e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
655e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
656e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
657e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __dip_output_actQ_all(FILE *ofp, struct actQ_info *p)
658e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
659e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | -------------\n");
660e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %13s\n", "Overall", "Avgs Reqs @ Q");
661e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %13.1lf\n", "Average",
662e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		(double)p->t_act_qs / (double)p->t_qs);
663e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
664e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
665e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_actQ_info(FILE *ofp)
666e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
667e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "%10s | %13s\n", "DEV", "Avg Reqs @ Q");
668e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "---------- | -------------\n");
669e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__dip_output_actQ, ofp);
670e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_actQs > 1)
671e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		__dip_output_actQ_all(ofp, &actQ_info);
672e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
673e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
674e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
675e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid output_histos(void)
676e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
677e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	int i;
678e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
679e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char fname[256];
680e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
681e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_name == NULL) return;
682e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
683e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	sprintf(fname, "%s_qhist.dat", output_name);
684e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ofp = my_fopen(fname, "w");
685e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (!ofp) {
686e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		perror(fname);
687e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return;
688e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
689e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
690e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# BTT histogram data\n");
691e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# Q buckets\n");
692e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	for (i = 0; i < (N_HIST_BKTS-1); i++)
693e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%4d %lld\n", (i+1), (long long)q_histo[i]);
694e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n# Q bucket for > %d\n%4d %lld\n", (int)N_HIST_BKTS-1,
695e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		N_HIST_BKTS-1, (long long)q_histo[N_HIST_BKTS-1]);
696e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fclose(ofp);
697e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
698e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	sprintf(fname, "%s_dhist.dat", output_name);
699e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	ofp = my_fopen(fname, "w");
700e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (!ofp) {
701e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		perror(fname);
702e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return;
703e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
704e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# D buckets\n");
705e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	for (i = 0; i < (N_HIST_BKTS-1); i++)
706e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%4d %lld\n", (i+1), (long long)d_histo[i]);
707e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n# D bucket for > %d\n%4d %lld\n", (int)N_HIST_BKTS-1,
708e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		N_HIST_BKTS-1, (long long)d_histo[N_HIST_BKTS-1]);
709e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fclose(ofp);
710e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
711e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
712e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint output_avgs(FILE *ofp)
713e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
714e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_all_data) {
715e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		if (exes == NULL || *exes != '\0') {
716e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_section_hdr(ofp, "Per Process");
717e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2Qdm", pip_q2q_dm_avg);
718e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2Adm", pip_q2a_dm_avg);
719e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2Cdm", pip_q2c_dm_avg);
720e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			fprintf(ofp, "\n");
721e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
722e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2Q", pip_q2q_avg);
723e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2A", pip_q2a_avg);
724e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2G", pip_q2g_avg);
725e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "S2G", pip_s2g_avg);
726e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "G2I", pip_g2i_avg);
727e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2M", pip_q2m_avg);
728e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "I2D", pip_i2d_avg);
729e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "D2C", pip_d2c_avg);
730e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			output_pip_avg(ofp, "Q2C", pip_q2c_avg);
731e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		}
732e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
733e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_section_hdr(ofp, "Per Device");
734e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2Qdm", dip_q2q_dm_avg);
735e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2Adm", dip_q2a_dm_avg);
736e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2Cdm", dip_q2c_dm_avg);
737e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "\n");
738e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
739e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2Q", dip_q2q_avg);
740e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2A", dip_q2a_avg);
741e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2G", dip_q2g_avg);
742e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "S2G", dip_s2g_avg);
743e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "G2I", dip_g2i_avg);
744e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2M", dip_q2m_avg);
745e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "I2D", dip_i2d_avg);
746e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "D2C", dip_d2c_avg);
747e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_dip_avg(ofp, "Q2C", dip_q2c_avg);
748e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
749e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
750e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "All Devices");
751e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_hdr(ofp, "ALL");
752e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2Qdm", &all_avgs.q2q_dm, 0);
753e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2Adm", &all_avgs.q2a_dm, 0);
754e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2Cdm", &all_avgs.q2c_dm, 0);
755e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
756e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
757e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2Q", &all_avgs.q2q, 1);
758e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2A", &all_avgs.q2a, 1);
759e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2G", &all_avgs.q2g, 1);
760e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "S2G", &all_avgs.s2g, 1);
761e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "G2I", &all_avgs.g2i, 1);
762e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2M", &all_avgs.q2m, 1);
763e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "I2D", &all_avgs.i2d, 1);
764e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "M2D", &all_avgs.m2d, 1);
765e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "D2C", &all_avgs.d2c, 1);
766e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_avg(ofp, "Q2C", &all_avgs.q2c, 1);
767e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
768e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
769e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Device Overhead");
770e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_dip_prep_ohead(ofp);
771e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
772e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Device Merge Information");
773e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_dip_merge_ratio(ofp);
774e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
775e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Device Q2Q Seek Information");
776e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_dip_q2q_seek_info(ofp);
777e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
778e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Device D2D Seek Information");
779e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_dip_seek_info(ofp);
780e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
781e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Plug Information");
782e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_plug_info(ofp);
783e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
784e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_section_hdr(ofp, "Active Requests At Q Information");
785e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_actQ_info(ofp);
786e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
787e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_histos();
788e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
789e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_all_data) {
790e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_section_hdr(ofp, "Q2D Histogram");
791e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		output_q2d_histo(ofp);
792e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
793e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
794e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return 0;
795e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
796e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
797e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_ranges(FILE *ofp, struct list_head *head_p, float base)
798e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
799e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct range_info *rip;
800e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct list_head *p;
801e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	float limit = base + 0.4;
802e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
803e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__list_for_each(p, head_p) {
804e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		rip = list_entry(p, struct range_info, head);
805e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%13.9lf %5.1f\n", BIT_TIME(rip->start), base);
806e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%13.9lf %5.1f\n", BIT_TIME(rip->start), limit);
807e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%13.9lf %5.1f\n", BIT_TIME(rip->end), limit);
808e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		fprintf(ofp, "%13.9lf %5.1f\n", BIT_TIME(rip->end), base);
809e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	}
810e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
811e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
812e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint output_regions(FILE *ofp, char *header, struct region_info *reg,
813e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat			  float base)
814e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
815e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (list_len(&reg->qranges) == 0 && list_len(&reg->cranges) == 0)
816e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		return 0;
817e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
818e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# %16s : q activity\n", header);
819e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_ranges(ofp, &reg->qranges, base);
820e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
821e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
822e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# %16s : c activity\n", header);
823e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	__output_ranges(ofp, &reg->cranges, base + 0.5);
824e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "\n");
825e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
826e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return 1;
827e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
828e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
829e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __od {
830e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
831e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	float base;
832e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
833e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_dev(struct d_info *dip, void *arg)
834e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
835e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	char header[128];
836e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __od *odp = arg;
837e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
838e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	sprintf(header, "%d,%d", MAJOR(dip->device), MINOR(dip->device));
839e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_regions(odp->ofp, header, &dip->regions, odp->base))
840e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		odp->base += 1.0;
841e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
842e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
843e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatfloat output_devs(FILE *ofp, float base)
844e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
845e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __od od = { .ofp = ofp, .base = base };
846e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
847e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# Per device\n" );
848e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	dip_foreach_out(__output_dev, &od);
849e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return od.base;
850e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
851e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
852e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstatic inline int exe_match(char *exe, char *name)
853e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
854e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return (exe == NULL) || (strstr(name, exe) != NULL);
855e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
856e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
857e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatstruct __op {
858e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	FILE *ofp;
859e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	float base;
860e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat};
861e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatvoid __output_procs(struct p_info *pip, void *arg)
862e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
863e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __op *opp = arg;
864e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	output_regions(opp->ofp, pip->name, &pip->regions, opp->base);
865e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	opp->base += 1.0;
866e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
867e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
868e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatfloat output_procs(FILE *ofp, float base)
869e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
870e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	struct __op op = { .ofp = ofp, .base = base };
871e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
872e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# Per process\n" );
873e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	pip_foreach_out(__output_procs, &op);
874e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return op.base;
875e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
876e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
877e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehatint output_ranges(FILE *ofp)
878e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat{
879e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	float base = 0.0;
880e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
881e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	fprintf(ofp, "# %s\n", "Total System");
882e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (output_regions(ofp, "Total System", &all_regions, base))
883e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		base += 1.0;
884e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
885e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	if (n_devs > 1)
886e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat		base = output_devs(ofp, base);
887e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
888e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	base = output_procs(ofp, base);
889e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat
890e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat	return 0;
891e20e1347b9914aa05e30548c15d7cd5e412cc0e2San Mehat}
892