/*
 * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
 * only version 2 as published by the Free Software Foundation.
 *
 * 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.
 */

/*
 *	A very simple perf program to periodically print the performance
 *	counter reqested on the command line to standard out at the rate
 *	specified.
 *
 *	This is valuable for showing the output in a simple plot or
 *	exporting the counter data for post processing.  No attempt
 *	to process the data is made.
 *
 *	Scaling is not supported, use only as many counters as are
 *	provided by the hardware.
 *
 *	Math functions are support to combine counter results by using
 *	the -m flag.
 *
 *	The -r -w flags supports user signalling for input. This assumes
 *	that a pipe/fifo is needed so the -rw cmd line arg is a string
 *	that is the name of the named pipe to open for read/write.  User
 *	sends data on the read pipe to the process to collect a sample.
 *	Commands are also supported on the pipe.
 *
 */

#include "perf.h"
#include "builtin.h"
#include "util/util.h"
#include "util/parse-options.h"
#include "util/parse-events.h"
#include "util/event.h"
#include "util/evsel.h"
#include "util/evlist.h"
#include "util/debug.h"
#include "util/header.h"
#include "util/cpumap.h"
#include "util/thread.h"
#include <signal.h>
#include <sys/types.h>

#define PERF_PERIODIC_ERROR -1

/* number of pieces of data on each read. */
#define DATA_SIZE 2

#define DEFAULT_FIFO_NAME "xxbadFiFo"
#define MAX_NAMELEN 50

struct perf_evlist *evsel_list;

/*
 * command line variables and settings
 * Default to current process, no_inherit, process
 */
static pid_t target_pid = -1; /* all */
static bool system_wide;
static int cpumask = -1;  /* all */
static int ncounts;
static int ms_sleep = 1000;  /* 1 second */
static char const *operations = "nnnnnnnnnnnnnnnn";  /* nop */
static bool math_enabled;
static bool calc_delta;
static double old_accum, accum;
static int math_op_index;
static char const *wfifo_name = DEFAULT_FIFO_NAME;
static char const *rfifo_name = DEFAULT_FIFO_NAME;
static bool use_fifo;
static bool is_ratio;
static FILE *fd_in, *fd_out;

static FILE *tReadFifo, *tWriteFifo;

/*
 * Raw results from perf, we track the current value and
 * the old value.
 */
struct perf_raw_results_s {
	u64 values;
	u64 old_value;
};

/*
 * Everything we need to support a perf counter across multiple
 * CPUs.  We need to support multiple file descriptors (perf_fd)
 * because perf requires a fd per counter, so 1 per core enabled.
 *
 * Raw results values are calculated across all the cores as they
 * are read.
 */
struct perf_setup_s {
	int event_index;
	struct perf_event_attr *attr;
	int perf_fd[MAX_NR_CPUS];
	pid_t pid;
	int cpu;
	int flags;
	int group;
	struct perf_raw_results_s data;
	struct perf_raw_results_s totals;
	struct perf_raw_results_s output;
};

static void do_cleanup(void)
{
	if (fd_in) {
		if (0 != fclose(fd_in))
			error("Error closing fd_in\n");
	}
	if (fd_out) {
		if (0 != fclose(fd_out))
			error("Error closing fd_out\n");
	}
	if (use_fifo) {
		if (0 != unlink(rfifo_name))
			error("Error unlinking rfifo\n");
		if (0 != unlink(wfifo_name))
			error("Error unlinking wfifo\n");
	}
}

/*
 * Unexpected signal for error indication, cleanup
 */
static int sig_dummy;
static void sig_do_cleanup(int sig)
{
	sig_dummy = sig;
	do_cleanup();
	exit(0);
}

#define PERIODIC_MAX_STRLEN 100
/*
 * Delay for either a timed period or the wait on the read_fifo
 */
static void delay(unsigned long milli)
{
	char tmp_stg[PERIODIC_MAX_STRLEN];
	int done;
	int ret;

	if (use_fifo) {
		do {
			done = true;
			ret = fscanf(tReadFifo, "%s", tmp_stg);
			if (ret == 0)
				return;
			/*
			 * Look for a command request, and if we get a command
			 * Need to process and then wait again w/o sending data.
			 */
			if (strncmp(tmp_stg, "PID", strnlen(tmp_stg,
				PERIODIC_MAX_STRLEN)) == 0) {
				fprintf(fd_out, " %u\n", getpid());
				fflush(fd_out);
				done = false;
			} else if (strncmp(tmp_stg, "EXIT",
					strnlen(tmp_stg, PERIODIC_MAX_STRLEN))
						== 0) {
				do_cleanup();
				exit(0);
			}

		} while (done != true);
	} else
		usleep(milli*1000);
}

/*
 * Create a perf counter event.
 * Some interesting behaviour that is not documented anywhere else:
 * the CPU will not work if out of range.
 * The CPU will only work for a single CPU, so to collect the counts
 * on the system in SMP based systems a counter needs to be created
 * for each CPU.
 */
static int create_perf_counter(struct perf_setup_s *p)
{
	struct cpu_map *cpus;
	int cpu;

	cpus = cpu_map__new(NULL);
	if (p == NULL)
		return PERF_PERIODIC_ERROR;
	for (cpu = 0; cpu < cpus->nr; cpu++) {
		if (((1 << cpu) & cpumask) == 0)
			continue;
		p->perf_fd[cpu] = sys_perf_event_open(p->attr, target_pid, cpu,
					-1, 0);
		if (p->perf_fd[cpu] < 0)
			return PERF_PERIODIC_ERROR;
	}
	return 0;
}

/*
 * Perf init setup
 */
static int perf_setup_init(struct perf_setup_s *p)
{
	if (p == NULL)
		return PERF_PERIODIC_ERROR;

	bzero(p, sizeof(struct perf_setup_s));
	p->group = -1;
	p->flags = 0;

	p->output.values = 0;
	p->output.old_value = 0;
	p->data.values = 0;
	p->data.old_value = 0;
	p->totals.old_value = 0;
	p->totals.values = 0;

	return 0;
}

/*
 * Read in ALL the performance counters configured for the CPU,
 * one performance monitor per core that was configured during
 * "all" mode
 */
static int perf_setup_read(struct perf_setup_s *p)
{
	u64 data[DATA_SIZE];
	int i, status;

	p->totals.values = 0;
	p->data.values = 0;
	for (i = 0; i < MAX_NR_CPUS; i++) {
		if (p->perf_fd[i] == 0)
			continue;
		status = read(p->perf_fd[i], &data, sizeof(data));
		p->data.values += data[0];
		p->totals.values += data[0];
	}

	/*
	 * Normally we show totals, we want to support
	 * showing deltas from the previous value so external apps do not have
	 * to do this...
	 */
	if (calc_delta) {
		p->output.values = p->data.values - p->data.old_value;
		p->data.old_value = p->data.values;
	} else
		p->output.values = p->totals.values;
	return 0;
}

static int perf_setup_show(struct perf_setup_s *p)
{
	if (p == NULL)
		return PERF_PERIODIC_ERROR;
	fprintf(fd_out, " %llu", p->output.values);
	return 0;
}


static const char * const periodic_usage[] = {
	"perf periodic [<options>]",
	NULL
};

static const struct option options[] = {
	OPT_CALLBACK('e', "event", &evsel_list, "event",
	"event selector. use 'perf list' to list available events",
	 parse_events_option),
	OPT_STRING('m', "math-operations", &operations, "nnnnnn",
	"math operation to perform on values collected asmd in order"),
	OPT_STRING('r', "readpipe", &rfifo_name, "xxbadFiFo",
	"wait for a user input fifo - will be created"),
	OPT_STRING('w', "writepipe", &wfifo_name, "xxbadFifo",
	"write data out on this pipe - pipe is created"),
	OPT_INTEGER('i', "increment", &ncounts,
	"number of times periods to count/iterate (default 0-forever)"),
	OPT_INTEGER('p', "pid", &target_pid,
	"stat events on existing process id"),
	OPT_INTEGER('c', "cpumask", &cpumask,
	"cpumask to enable counters, default all (-1)"),
	OPT_INTEGER('s', "sleep", &ms_sleep,
	"how long to sleep in ms between each sample (default 1000)"),
	OPT_BOOLEAN('a', "all-cpus", &system_wide,
	"system-wide collection from all CPUs overrides cpumask"),
	OPT_BOOLEAN('d', "delta", &calc_delta,
	"calculate and display the delta values math funcs will use delta"),
	OPT_INCR('v', "verbose", &verbose,
	"be more verbose (show counter open errors, etc)"),
	OPT_END()
};

/*
 * After every period we reset any math that was performed.
 */
static void reset_math(void)
{
	math_op_index = 0;
	old_accum = accum;
	accum = 0;
}

static void do_math_op(struct perf_setup_s *p)
{
	if (!math_enabled)
		return;
	switch (operations[math_op_index++]) {
	case 'm':
		accum *= (double)p->output.values; break;
	case 'a':
		accum += (double)p->output.values; break;
	case 's':
		accum -= (double)p->output.values; break;
	case 'd':
		accum /= (double)p->output.values; break;
	case 'z':
		accum =  0; break;
	case 't':
		accum =  (double)p->output.values; break; /*transfer*/
	case 'T':
		accum +=  old_accum; break; /*total*/
	case 'i':	/* ignore */
	default:
		break;
	}
}

int cmd_periodic(int argc, const char **argv, const char *prefix __used)
{
	int status = 0;
	int c, i;
	struct perf_setup_s *p[MAX_COUNTERS];
	struct perf_evsel *counter;
	FILE *fp;
	int nr_counters = 0;

	evsel_list = perf_evlist__new(NULL, NULL);
	if (evsel_list == NULL)
		return -ENOMEM;

	argc = parse_options(argc, argv, options, periodic_usage,
		PARSE_OPT_STOP_AT_NON_OPTION);

	if (system_wide)
		cpumask = -1;

	/*
	 * The r & w option redirects stdout to a newly created pipe and
	 * waits for input on the read pipe before continuing
	 */
	fd_in = stdin;
	fd_out = stdout;
	if (strncmp(rfifo_name, DEFAULT_FIFO_NAME,
				strnlen(rfifo_name, MAX_NAMELEN))) {
		fp = fopen(rfifo_name, "r");
		if (fp != NULL) {
			fclose(fp);
			remove(rfifo_name);
		}
		if (mkfifo(rfifo_name, 0777) == -1) {
			error("Could not open read fifo\n");
			do_cleanup();
			return PERF_PERIODIC_ERROR;
		}
		tReadFifo = fopen(rfifo_name, "r+");
		if (tReadFifo == 0) {
			do_cleanup();
			error("Could not open read fifo file\n");
			return PERF_PERIODIC_ERROR;
		}
		use_fifo = true;
	}
	if (strncmp(wfifo_name, DEFAULT_FIFO_NAME,
				strnlen(wfifo_name, MAX_NAMELEN)))  {
		fp = fopen(wfifo_name, "r");
		if (fp != NULL) {
			fclose(fp);
			remove(wfifo_name);
		}
		if (mkfifo(wfifo_name, 0777) == -1) {
			do_cleanup();
			error("Could not open write fifo\n");
			return PERF_PERIODIC_ERROR;
		}
		fd_out = fopen(wfifo_name, "w+");
		if (fd_out == 0) {
			do_cleanup();
			error("Could not open write fifo file\n");
			return PERF_PERIODIC_ERROR;
		}
		tWriteFifo = fd_out;
	}

	math_enabled = (operations[0] != 'n');

	/*
	 * If we don't ignore SIG_PIPE then when the other side
	 * of a pipe closes we shutdown too...
	 */
	signal(SIGPIPE, SIG_IGN);
	signal(SIGINT, sig_do_cleanup);
	signal(SIGQUIT, sig_do_cleanup);
	signal(SIGKILL, sig_do_cleanup);
	signal(SIGTERM, sig_do_cleanup);

	i = 0;
	list_for_each_entry(counter, &evsel_list->entries, node) {
		p[i] = malloc(sizeof(struct perf_setup_s));
		if (p[i] == NULL) {
			error("Error allocating perf_setup_s\n");
			do_cleanup();
			return PERF_PERIODIC_ERROR;
		}
		bzero(p[i], sizeof(struct perf_setup_s));
		perf_setup_init(p[i]);
		p[i]->attr = &(counter->attr);
		p[i]->event_index = counter->idx;
		if (create_perf_counter(p[i]) < 0) {
			do_cleanup();
			die("Not all events could be opened.\n");
			return PERF_PERIODIC_ERROR;
		}
		i++;
		nr_counters++;
	}
	i = 0;
	while (1) {

		/*
		 * Wait first otherwise single sample will print w/o signal
		 * when using the -u (user signal) flag
		 */
		delay(ms_sleep);

		/*
		 * Do the collection, read and then perform any math operations
		 */
		for (c = 0; c < nr_counters; c++) {
			status = perf_setup_read(p[c]);
			do_math_op(p[c]);
		}

		/*
		 * After all collection and math, we perform one last math
		 * to allow totaling, if enabled etc, then either printout
		 * a single float value when the math is enabled or ...
		 */
		if (math_enabled) {
			do_math_op(p[c]);
			if (is_ratio)
				fprintf(fd_out, "%#f\n", accum*100);
			else
				fprintf(fd_out, "%#f\n", accum);
		} else {
			/*
			 * ... print out one integer value for each counter
			 */
			for (c = 0; c < nr_counters; c++)
				status = perf_setup_show(p[c]);
			fprintf(fd_out, "\n");
		}

		/*
		 * Did the user give us an iteration count?
		 */
		if ((ncounts != 0) && (++i >= ncounts))
			break;
		reset_math();
		fflush(fd_out); /* make sure data is flushed out the pipe*/
	}

	do_cleanup();

	return status;
}
