/*
 * Copyright (c) 1991, 1992 Paul Kranenburg <pk@cs.few.eur.nl>
 * Copyright (c) 1993 Branko Lankester <branko@hacktic.nl>
 * Copyright (c) 1993, 1994, 1995, 1996 Rick Sladkey <jrs@world.std.com>
 * Copyright (c) 1996-1999 Wichert Akkerman <wichert@cistron.nl>
 * Copyright (c) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *                     Linux for s390 port by D.J. Barrow
 *                    <barrow_dj@mail.yahoo.com,djbarrow@de.ibm.com>
 * Copyright (c) 2004 Roland McGrath <roland@redhat.com>
 * Copyright (c) 2006 Dmitry V. Levin <ldv@altlinux.org>
 * Copyright (c) 2006-2017 The strace developers.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "defs.h"

/* Per-syscall stats structure */
struct call_counts {
	/* time may be total latency or system time */
	struct timeval time;
	int calls, errors;
};

static struct call_counts *countv[SUPPORTED_PERSONALITIES];
#define counts (countv[current_personality])

static struct timeval shortest = { 1000000, 0 };

void
count_syscall(struct tcb *tcp, const struct timeval *syscall_exiting_tv)
{
	struct timeval wtv;
	struct timeval *tv = &wtv;
	struct call_counts *cc;

	if (!scno_in_range(tcp->scno))
		return;

	if (!counts)
		counts = xcalloc(nsyscalls, sizeof(*counts));
	cc = &counts[tcp->scno];

	cc->calls++;
	if (syserror(tcp))
		cc->errors++;

	/* tv = wall clock time spent while in syscall */
	tv_sub(tv, syscall_exiting_tv, &tcp->etime);

	/* Spent more wall clock time than spent system time? (usually yes) */
	if (tv_cmp(tv, &tcp->dtime) > 0) {
		static struct timeval one_tick = { -1, 0 };

		if (one_tick.tv_sec == -1) {
			/* Initialize it.  */
			struct itimerval it;

			memset(&it, 0, sizeof(it));
			it.it_interval.tv_usec = 1;
			setitimer(ITIMER_REAL, &it, NULL);
			getitimer(ITIMER_REAL, &it);
			one_tick = it.it_interval;
//FIXME: this hack doesn't work (tested on linux-3.6.11): one_tick = 0.000000
//tprintf(" one_tick.tv_usec:%u\n", (unsigned)one_tick.tv_usec);
		}

		if (tv_nz(&tcp->dtime))
			/* tv = system time spent, if it isn't 0 */
			tv = &tcp->dtime;
		else if (tv_cmp(tv, &one_tick) > 0) {
			/* tv = smallest "sane" time interval */
			if (tv_cmp(&shortest, &one_tick) < 0)
				tv = &shortest;
			else
				tv = &one_tick;
		}
	}
	if (tv_cmp(tv, &shortest) < 0)
		shortest = *tv;
	tv_add(&cc->time, &cc->time, count_wallclock ? &wtv : tv);
}

static int
time_cmp(void *a, void *b)
{
	return -tv_cmp(&counts[*((int *) a)].time,
		       &counts[*((int *) b)].time);
}

static int
syscall_cmp(void *a, void *b)
{
	const char *a_name = sysent[*((int *) a)].sys_name;
	const char *b_name = sysent[*((int *) b)].sys_name;
	return strcmp(a_name ? a_name : "", b_name ? b_name : "");
}

static int
count_cmp(void *a, void *b)
{
	int     m = counts[*((int *) a)].calls;
	int     n = counts[*((int *) b)].calls;

	return (m < n) ? 1 : (m > n) ? -1 : 0;
}

static int (*sortfun)();
static struct timeval overhead = { -1, -1 };

void
set_sortby(const char *sortby)
{
	if (strcmp(sortby, "time") == 0)
		sortfun = time_cmp;
	else if (strcmp(sortby, "calls") == 0)
		sortfun = count_cmp;
	else if (strcmp(sortby, "name") == 0)
		sortfun = syscall_cmp;
	else if (strcmp(sortby, "nothing") == 0)
		sortfun = NULL;
	else {
		error_msg_and_help("invalid sortby: '%s'", sortby);
	}
}

void set_overhead(int n)
{
	overhead.tv_sec = n / 1000000;
	overhead.tv_usec = n % 1000000;
}

static void
call_summary_pers(FILE *outf)
{
	unsigned int i;
	int     call_cum, error_cum;
	struct timeval tv_cum, dtv;
	double  float_tv_cum;
	double  percent;
	const char *dashes = "----------------";
	char    error_str[sizeof(int)*3];
	int    *sorted_count;

	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
		"% time", "seconds", "usecs/call",
		"calls", "errors", "syscall");
	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
		dashes, dashes, dashes, dashes, dashes, dashes);

	sorted_count = xcalloc(sizeof(int), nsyscalls);
	call_cum = error_cum = tv_cum.tv_sec = tv_cum.tv_usec = 0;
	if (overhead.tv_sec == -1) {
		tv_mul(&overhead, &shortest, 8);
		tv_div(&overhead, &overhead, 10);
	}
	for (i = 0; i < nsyscalls; i++) {
		sorted_count[i] = i;
		if (counts == NULL || counts[i].calls == 0)
			continue;
		tv_mul(&dtv, &overhead, counts[i].calls);
		tv_sub(&counts[i].time, &counts[i].time, &dtv);
		call_cum += counts[i].calls;
		error_cum += counts[i].errors;
		tv_add(&tv_cum, &tv_cum, &counts[i].time);
	}
	float_tv_cum = tv_float(&tv_cum);
	if (counts) {
		if (sortfun)
			qsort((void *) sorted_count, nsyscalls, sizeof(int), sortfun);
		for (i = 0; i < nsyscalls; i++) {
			double float_syscall_time;
			int idx = sorted_count[i];
			struct call_counts *cc = &counts[idx];
			if (cc->calls == 0)
				continue;
			tv_div(&dtv, &cc->time, cc->calls);
			error_str[0] = '\0';
			if (cc->errors)
				sprintf(error_str, "%u", cc->errors);
			float_syscall_time = tv_float(&cc->time);
			percent = (100.0 * float_syscall_time);
			if (percent != 0.0)
				   percent /= float_tv_cum;
			/* else: float_tv_cum can be 0.0 too and we get 0/0 = NAN */
			fprintf(outf, "%6.2f %11.6f %11lu %9u %9.9s %s\n",
				percent, float_syscall_time,
				(long) (1000000 * dtv.tv_sec + dtv.tv_usec),
				cc->calls,
				error_str, sysent[idx].sys_name);
		}
	}
	free(sorted_count);

	fprintf(outf, "%6.6s %11.11s %11.11s %9.9s %9.9s %s\n",
		dashes, dashes, dashes, dashes, dashes, dashes);
	error_str[0] = '\0';
	if (error_cum)
		sprintf(error_str, "%u", error_cum);
	fprintf(outf, "%6.6s %11.6f %11.11s %9u %9.9s %s\n",
		"100.00", float_tv_cum, "",
		call_cum, error_str, "total");
}

void
call_summary(FILE *outf)
{
	unsigned int i, old_pers = current_personality;

	for (i = 0; i < SUPPORTED_PERSONALITIES; ++i) {
		if (!countv[i])
			continue;

		if (current_personality != i)
			set_personality(i);
		if (i)
			fprintf(outf,
				"System call usage summary for %d bit mode:\n",
				current_wordsize * 8);
		call_summary_pers(outf);
	}

	if (old_pers != current_personality)
		set_personality(old_pers);
}
