/*
 * mem-memcpy.c
 *
 * memcpy: Simple memory copy in various ways
 *
 * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
 */
#include <ctype.h>

#include "../perf.h"
#include "../util/util.h"
#include "../util/parse-options.h"
#include "../util/string.h"
#include "../util/header.h"
#include "bench.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <errno.h>

#define K 1024

static const char	*length_str	= "1MB";
static const char	*routine	= "default";
static int		use_clock	= 0;
static int		clock_fd;

static const struct option options[] = {
	OPT_STRING('l', "length", &length_str, "1MB",
		    "Specify length of memory to copy. "
		    "available unit: B, MB, GB (upper and lower)"),
	OPT_STRING('r', "routine", &routine, "default",
		    "Specify routine to copy"),
	OPT_BOOLEAN('c', "clock", &use_clock,
		    "Use CPU clock for measuring"),
	OPT_END()
};

struct routine {
	const char *name;
	const char *desc;
	void * (*fn)(void *dst, const void *src, size_t len);
};

struct routine routines[] = {
	{ "default",
	  "Default memcpy() provided by glibc",
	  memcpy },
	{ NULL,
	  NULL,
	  NULL   }
};

static const char * const bench_mem_memcpy_usage[] = {
	"perf bench mem memcpy <options>",
	NULL
};

static struct perf_event_attr clock_attr = {
	.type		= PERF_TYPE_HARDWARE,
	.config		= PERF_COUNT_HW_CPU_CYCLES
};

static void init_clock(void)
{
	clock_fd = sys_perf_event_open(&clock_attr, getpid(), -1, -1, 0);

	if (clock_fd < 0 && errno == ENOSYS)
		die("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
	else
		BUG_ON(clock_fd < 0);
}

static u64 get_clock(void)
{
	int ret;
	u64 clk;

	ret = read(clock_fd, &clk, sizeof(u64));
	BUG_ON(ret != sizeof(u64));

	return clk;
}

static double timeval2double(struct timeval *ts)
{
	return (double)ts->tv_sec +
		(double)ts->tv_usec / (double)1000000;
}

int bench_mem_memcpy(int argc, const char **argv,
		     const char *prefix __used)
{
	int i;
	void *dst, *src;
	size_t length;
	double bps = 0.0;
	struct timeval tv_start, tv_end, tv_diff;
	u64 clock_start, clock_end, clock_diff;

	clock_start = clock_end = clock_diff = 0ULL;
	argc = parse_options(argc, argv, options,
			     bench_mem_memcpy_usage, 0);

	tv_diff.tv_sec = 0;
	tv_diff.tv_usec = 0;
	length = (size_t)perf_atoll((char *)length_str);

	if ((s64)length <= 0) {
		fprintf(stderr, "Invalid length:%s\n", length_str);
		return 1;
	}

	for (i = 0; routines[i].name; i++) {
		if (!strcmp(routines[i].name, routine))
			break;
	}
	if (!routines[i].name) {
		printf("Unknown routine:%s\n", routine);
		printf("Available routines...\n");
		for (i = 0; routines[i].name; i++) {
			printf("\t%s ... %s\n",
			       routines[i].name, routines[i].desc);
		}
		return 1;
	}

	dst = zalloc(length);
	if (!dst)
		die("memory allocation failed - maybe length is too large?\n");

	src = zalloc(length);
	if (!src)
		die("memory allocation failed - maybe length is too large?\n");

	if (bench_format == BENCH_FORMAT_DEFAULT) {
		printf("# Copying %s Bytes from %p to %p ...\n\n",
		       length_str, src, dst);
	}

	if (use_clock) {
		init_clock();
		clock_start = get_clock();
	} else {
		BUG_ON(gettimeofday(&tv_start, NULL));
	}

	routines[i].fn(dst, src, length);

	if (use_clock) {
		clock_end = get_clock();
		clock_diff = clock_end - clock_start;
	} else {
		BUG_ON(gettimeofday(&tv_end, NULL));
		timersub(&tv_end, &tv_start, &tv_diff);
		bps = (double)((double)length / timeval2double(&tv_diff));
	}

	switch (bench_format) {
	case BENCH_FORMAT_DEFAULT:
		if (use_clock) {
			printf(" %14lf Clock/Byte\n",
			       (double)clock_diff / (double)length);
		} else {
			if (bps < K)
				printf(" %14lf B/Sec\n", bps);
			else if (bps < K * K)
				printf(" %14lfd KB/Sec\n", bps / 1024);
			else if (bps < K * K * K)
				printf(" %14lf MB/Sec\n", bps / 1024 / 1024);
			else {
				printf(" %14lf GB/Sec\n",
				       bps / 1024 / 1024 / 1024);
			}
		}
		break;
	case BENCH_FORMAT_SIMPLE:
		if (use_clock) {
			printf("%14lf\n",
			       (double)clock_diff / (double)length);
		} else
			printf("%lf\n", bps);
		break;
	default:
		/* reaching this means there's some disaster: */
		die("unknown format: %d\n", bench_format);
		break;
	}

	return 0;
}
