/*
 * blktrace output analysis: generate a timeline & gather statistics
 *
 * Copyright (C) 2006 Alan D. Brunelle <Alan.Brunelle@hp.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
 *
 */
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#include "globals.h"

char bt_timeline_version[] = "2.09";

char *devices, *exes, *input_name, *output_name, *seek_name, *bno_dump_name;
char *d2c_name, *q2c_name, *per_io_name, *unplug_hist_name;
char *sps_name, *aqd_name, *q2d_name, *per_io_trees;
FILE *rngs_ofp, *avgs_ofp, *xavgs_ofp, *per_io_ofp, *msgs_ofp;
int verbose, done, time_bounded, output_all_data, seek_absolute;
int easy_parse_avgs, ignore_remaps, do_p_live;
double t_astart, t_aend, last_t_seen;
unsigned long n_traces;
struct avgs_info all_avgs;
unsigned int n_devs;
time_t genesis, last_vtrace;
LIST_HEAD(all_devs);
LIST_HEAD(all_procs);
LIST_HEAD(all_ios);
LIST_HEAD(free_ios);
LIST_HEAD(free_bilinks);
__u64 q_histo[N_HIST_BKTS], d_histo[N_HIST_BKTS];

double plat_freq = 0.0;
double range_delta = 0.1;
__u64 last_q = (__u64)-1;

struct region_info all_regions = {
	.qranges = LIST_HEAD_INIT(all_regions.qranges),
	.cranges = LIST_HEAD_INIT(all_regions.cranges),
};

int process(void);

int main(int argc, char *argv[])
{
	handle_args(argc, argv);

	init_dev_heads();
	iostat_init();
	if (!rstat_init())
		return 1;

	if (process() || output_avgs(avgs_ofp) || output_ranges(rngs_ofp))
		return 1;

	if (iostat_ofp) {
		fprintf(iostat_ofp, "\n");
		iostat_dump_stats(iostat_last_stamp, 1);
	}

	if (msgs_ofp != stdout)
		fclose(msgs_ofp);
	if (rngs_ofp != stdout)
		fclose(rngs_ofp);
	if (avgs_ofp != stdout)
		fclose(avgs_ofp);
	if (xavgs_ofp)
		fclose(xavgs_ofp);

	dip_cleanup();
	dev_map_exit();
	dip_exit();
	rstat_exit();
	pip_exit();
	io_free_all();
	region_exit(&all_regions);
	p_live_exit();
	clean_allocs();

	return 0;
}

static inline double tv2dbl(struct timeval *tv)
{
	return (double)tv->tv_sec + (((double)tv->tv_usec) / (1000.0 * 1000.0));
}

int process(void)
{
	int ret = 0;
	struct io *iop = io_alloc();
	struct timeval tvs, tve;

	genesis = last_vtrace = time(NULL);
	gettimeofday(&tvs, NULL);
	while (!done && next_trace(&iop->t, &iop->pdu)) {
		add_trace(iop);
		iop = io_alloc();
	}

	io_release(iop);
	gettimeofday(&tve, NULL);

	if (verbose) {
		double tps, dt_input = tv2dbl(&tve) - tv2dbl(&tvs);

		tps = (double)n_traces / dt_input;
		printf("\r                                        "
		       "                                        \r");
		printf("%10lu traces @ %.1lf Ktps in %.6lf seconds\n",
			n_traces, tps/1000.0,
			dt_input);
	}

	return ret;
}
