/*
 * 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);
}
