// SPDX-License-Identifier: GPL-2.0
/*
 * mem-memcpy.c
 *
 * Simple memcpy() and memset() benchmarks
 *
 * Written by Hitoshi Mitake <mitake@dcl.info.waseda.ac.jp>
 */

#include "bench.h"
#include "../perf-sys.h"
#include <subcmd/parse-options.h>
#include "util/cloexec.h"
#include "util/debug.h"
#include "util/header.h"
#include "util/stat.h"
#include "util/string2.h"
#include "mem-memcpy-arch.h"
#include "mem-memset-arch.h"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <errno.h>
#include <linux/time64.h>
#include <linux/log2.h>
#include <pthread.h>

#define K 1024

#define PAGE_SHIFT_4KB		12
#define PAGE_SHIFT_2MB		21
#define PAGE_SHIFT_1GB		30

static const char	*size_str	= "1MB";
static const char	*function_str	= "all";
static const char	*page_size_str	= "4KB";
static const char	*chunk_size_str	= "0";
static unsigned int	nr_loops	= 1;
static bool		use_cycles;
static int		cycles_fd;
static unsigned int	seed;
static unsigned int	nr_threads	= 1;

static const struct option bench_common_options[] = {
	OPT_STRING('s', "size", &size_str, "1MB",
		    "Specify the size of the memory buffers. "
		    "Available units: B, KB, MB, GB and TB (case insensitive)"),

	OPT_STRING('p', "page", &page_size_str, "4KB",
		    "Specify page-size for mapping memory buffers. "
		    "Available sizes: 4KB, 2MB, 1GB (case insensitive)"),

	OPT_STRING('f', "function", &function_str, "all",
		    "Specify the function to run, \"all\" runs all available functions, \"help\" lists them"),

	OPT_UINTEGER('l', "nr_loops", &nr_loops,
		    "Specify the number of loops to run. (default: 1)"),

	OPT_BOOLEAN('c', "cycles", &use_cycles,
		    "Use a cycles event instead of gettimeofday() to measure performance"),

	OPT_END()
};

static const struct option bench_mem_options[] = {
	OPT_STRING('k', "chunk", &chunk_size_str, "0",
		    "Specify the chunk-size for each invocation. "
		    "Available units: B, KB, MB, GB and TB (case insensitive)"),
	OPT_PARENT(bench_common_options),
	OPT_END()
};

union bench_clock {
	u64		cycles;
	struct timeval	tv;
};

struct bench_params {
	size_t		size;
	size_t		size_total;
	size_t		chunk_size;
	unsigned int	nr_loops;
	unsigned int	page_shift;
	unsigned int	seed;
};

struct bench_mem_info {
	const struct function *functions;
	int (*do_op)(const struct function *r, struct bench_params *p,
		     void *src, void *dst, union bench_clock *rt);
	const char *const *usage;
	const struct option *options;
	bool alloc_src;
};

typedef bool (*mem_init_t)(struct bench_mem_info *, struct bench_params *,
			   void **, void **);
typedef void (*mem_fini_t)(struct bench_mem_info *, struct bench_params *,
			   void **, void **);
typedef void *(*memcpy_t)(void *, const void *, size_t);
typedef void *(*memset_t)(void *, int, size_t);
typedef void (*mmap_op_t)(void *, size_t, unsigned int, bool);

struct function {
	const char *name;
	const char *desc;
	struct {
		mem_init_t init;
		mem_fini_t fini;
		union {
			memcpy_t memcpy;
			memset_t memset;
			mmap_op_t mmap_op;
		};
	} fn;
};

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

static struct stats stats;

static int init_cycles(void)
{
	cycles_fd = sys_perf_event_open(&cycle_attr, getpid(), -1, -1, perf_event_open_cloexec_flag());

	if (cycles_fd < 0 && errno == ENOSYS) {
		pr_debug("No CONFIG_PERF_EVENTS=y kernel support configured?\n");
		return -1;
	}

	return cycles_fd;
}

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

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

	return clk;
}

static void clock_get(union bench_clock *t)
{
	if (use_cycles)
		t->cycles = get_cycles();
	else
		BUG_ON(gettimeofday(&t->tv, NULL));
}

static union bench_clock clock_diff(union bench_clock *s, union bench_clock *e)
{
	union bench_clock t;

	if (use_cycles)
		t.cycles = e->cycles - s->cycles;
	else
		timersub(&e->tv, &s->tv, &t.tv);

	return t;
}

static void clock_accum(union bench_clock *a, union bench_clock *b)
{
	if (use_cycles)
		a->cycles += b->cycles;
	else
		timeradd(&a->tv, &b->tv, &a->tv);
}

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

#define print_bps(x) do {						\
		if (x < K)						\
			printf(" %14lf bytes/sec", x);			\
		else if (x < K * K)					\
			printf(" %14lfd KB/sec", x / K);		\
		else if (x < K * K * K)					\
			printf(" %14lf MB/sec", x / K / K);		\
		else							\
			printf(" %14lf GB/sec", x / K / K / K);	\
	} while (0)

static void __bench_mem_function(struct bench_mem_info *info, struct bench_params *p,
				 int r_idx)
{
	const struct function *r = &info->functions[r_idx];
	double result_bps = 0.0;
	union bench_clock rt = { 0 };
	void *src = NULL, *dst = NULL;

	init_stats(&stats);
	printf("# function '%s' (%s)\n", r->name, r->desc);

	if (r->fn.init && r->fn.init(info, p, &src, &dst))
		goto out_init_failed;

	if (bench_format == BENCH_FORMAT_DEFAULT)
		printf("# Copying %s bytes ...\n\n", size_str);

	if (info->do_op(r, p, src, dst, &rt))
		goto out_test_failed;

	switch (bench_format) {
	case BENCH_FORMAT_DEFAULT:
		if (use_cycles) {
			printf(" %14lf cycles/byte", (double)rt.cycles/(double)p->size_total);
		} else {
			result_bps = (double)p->size_total/timeval2double(&rt.tv);
			print_bps(result_bps);
		}
		if (nr_threads > 1) {
			printf("/thread\t( +- %6.2f%% )",
			       rel_stddev_stats(stddev_stats(&stats), avg_stats(&stats)));
		}
		printf("\n");
		break;

	case BENCH_FORMAT_SIMPLE:
		if (use_cycles) {
			printf("%lf\n", (double)rt.cycles/(double)p->size_total);
		} else {
			result_bps = (double)p->size_total/timeval2double(&rt.tv);
			printf("%lf\n", result_bps);
		}
		break;

	default:
		BUG_ON(1);
		break;
	}

out_test_failed:
out_free:
	if (r->fn.fini) r->fn.fini(info, p, &src, &dst);
	return;
out_init_failed:
	printf("# Memory allocation failed - maybe size (%s) %s?\n", size_str,
			p->page_shift != PAGE_SHIFT_4KB ? "has insufficient hugepages" : "is too large");
	goto out_free;
}

static int bench_mem_common(int argc, const char **argv, struct bench_mem_info *info)
{
	int i;
	struct bench_params p = { 0 };
	unsigned int page_size;

	argc = parse_options(argc, argv, info->options, info->usage, 0);

	if (use_cycles) {
		i = init_cycles();
		if (i < 0) {
			fprintf(stderr, "Failed to open cycles counter\n");
			return i;
		}
	}

	p.nr_loops = nr_loops;
	p.size = (size_t)perf_atoll((char *)size_str);

	if ((s64)p.size <= 0) {
		fprintf(stderr, "Invalid size:%s\n", size_str);
		return 1;
	}
	p.size_total = p.size * p.nr_loops;

	p.chunk_size = (size_t)perf_atoll((char *)chunk_size_str);
	if ((s64)p.chunk_size < 0 || (s64)p.chunk_size > (s64)p.size) {
		fprintf(stderr, "Invalid chunk_size:%s\n", chunk_size_str);
		return 1;
	}
	if (!p.chunk_size)
		p.chunk_size = p.size;

	page_size = (unsigned int)perf_atoll((char *)page_size_str);
	if (page_size != (1 << PAGE_SHIFT_4KB) &&
	    page_size != (1 << PAGE_SHIFT_2MB) &&
	    page_size != (1 << PAGE_SHIFT_1GB)) {
		fprintf(stderr, "Invalid page-size:%s\n", page_size_str);
		return 1;
	}
	p.page_shift = ilog2(page_size);

	p.seed = seed;

	if (!strncmp(function_str, "all", 3)) {
		for (i = 0; info->functions[i].name; i++)
			__bench_mem_function(info, &p, i);
		return 0;
	}

	for (i = 0; info->functions[i].name; i++) {
		if (!strcmp(info->functions[i].name, function_str))
			break;
	}
	if (!info->functions[i].name) {
		if (strcmp(function_str, "help") && strcmp(function_str, "h"))
			printf("Unknown function: %s\n", function_str);
		printf("Available functions:\n");
		for (i = 0; info->functions[i].name; i++) {
			printf("\t%s ... %s\n",
			       info->functions[i].name, info->functions[i].desc);
		}
		return 1;
	}

	__bench_mem_function(info, &p, i);

	return 0;
}

static void memcpy_prefault(memcpy_t fn, size_t size, void *src, void *dst)
{
	/* Make sure to always prefault zero pages even if MMAP_THRESH is crossed: */
	memset(src, 0, size);

	/*
	 * We prefault the freshly allocated memory range here,
	 * to not measure page fault overhead:
	 */
	fn(dst, src, size);
}

static int do_memcpy(const struct function *r, struct bench_params *p,
		     void *src, void *dst, union bench_clock *rt)
{
	union bench_clock start, end;
	memcpy_t fn = r->fn.memcpy;

	memcpy_prefault(fn, p->size, src, dst);

	clock_get(&start);
	for (unsigned int i = 0; i < p->nr_loops; ++i)
		for (size_t off = 0; off < p->size; off += p->chunk_size)
			fn(dst + off, src + off, min(p->chunk_size, p->size - off));
	clock_get(&end);

	*rt = clock_diff(&start, &end);

	return 0;
}

static void *bench_mmap(size_t size, bool populate, unsigned int page_shift)
{
	void *p;
	int extra = populate ? MAP_POPULATE : 0;

	if (page_shift != PAGE_SHIFT_4KB)
		extra |= MAP_HUGETLB | (page_shift << MAP_HUGE_SHIFT);

	p = mmap(NULL, size, PROT_READ|PROT_WRITE,
		 extra | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);

	return p == MAP_FAILED ? NULL : p;
}

static void bench_munmap(void *p, size_t size)
{
	if (p)
		munmap(p, size);
}

static bool mem_alloc(struct bench_mem_info *info, struct bench_params *p,
		      void **src, void **dst)
{
	bool failed;

	*dst = bench_mmap(p->size, true, p->page_shift);
	failed = *dst == NULL;

	if (info->alloc_src) {
		*src = bench_mmap(p->size, true, p->page_shift);
		failed = failed || *src == NULL;
	}

	return failed;
}

static void mem_free(struct bench_mem_info *info __maybe_unused,
		     struct bench_params *p __maybe_unused,
		     void **src, void **dst)
{
	bench_munmap(*dst, p->size);
	bench_munmap(*src, p->size);

	*dst = *src = NULL;
}

static struct function memcpy_functions[] = {
	{ .name		= "default",
	  .desc		= "Default memcpy() provided by glibc",
	  .fn.init	= mem_alloc,
	  .fn.fini	= mem_free,
	  .fn.memcpy	= memcpy },

#ifdef HAVE_ARCH_X86_64_SUPPORT
# define MEMCPY_FN(_fn, _init, _fini, _name, _desc)	\
	{.name = _name, .desc = _desc, .fn.memcpy = _fn, .fn.init = _init, .fn.fini = _fini },
# include "mem-memcpy-x86-64-asm-def.h"
# undef MEMCPY_FN
#endif

	{ .name = NULL, }
};

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

int bench_mem_memcpy(int argc, const char **argv)
{
	struct bench_mem_info info = {
		.functions		= memcpy_functions,
		.do_op			= do_memcpy,
		.usage			= bench_mem_memcpy_usage,
		.options		= bench_mem_options,
		.alloc_src              = true,
	};

	return bench_mem_common(argc, argv, &info);
}

static int do_memset(const struct function *r, struct bench_params *p,
		     void *src __maybe_unused, void *dst, union bench_clock *rt)
{
	union bench_clock start, end;
	memset_t fn = r->fn.memset;

	/*
	 * We prefault the freshly allocated memory range here,
	 * to not measure page fault overhead:
	 */
	fn(dst, -1, p->size);

	clock_get(&start);
	for (unsigned int i = 0; i < p->nr_loops; ++i)
		for (size_t off = 0; off < p->size; off += p->chunk_size)
			fn(dst + off, i, min(p->chunk_size, p->size - off));
	clock_get(&end);

	*rt = clock_diff(&start, &end);

	return 0;
}

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

static const struct function memset_functions[] = {
	{ .name		= "default",
	  .desc		= "Default memset() provided by glibc",
	  .fn.init	= mem_alloc,
	  .fn.fini	= mem_free,
	  .fn.memset	= memset },

#ifdef HAVE_ARCH_X86_64_SUPPORT
# define MEMSET_FN(_fn, _init, _fini, _name, _desc) \
	{.name = _name, .desc = _desc, .fn.memset = _fn, .fn.init = _init, .fn.fini = _fini },
# include "mem-memset-x86-64-asm-def.h"
# undef MEMSET_FN
#endif

	{ .name = NULL, }
};

int bench_mem_memset(int argc, const char **argv)
{
	struct bench_mem_info info = {
		.functions		= memset_functions,
		.do_op			= do_memset,
		.usage			= bench_mem_memset_usage,
		.options		= bench_mem_options,
	};

	return bench_mem_common(argc, argv, &info);
}

static void mmap_page_touch(void *dst, size_t size, unsigned int page_shift, bool random)
{
	unsigned long npages = size / (1 << page_shift);
	unsigned long offset = 0, r = 0;

	for (unsigned long i = 0; i < npages; i++) {
		if (random)
			r = rand() % (1 << page_shift);

		*((char *)dst + offset + r) = *(char *)(dst + offset + r) + i;
		offset += 1 << page_shift;
	}
}

struct mmap_data {
	pthread_t id;
	const struct function *func;
	struct bench_params *params;
	union bench_clock result;
	unsigned int seed;
	int error;
};

static void *do_mmap_thread(void *arg)
{
	struct mmap_data *data = arg;
	const struct function *r = data->func;
	struct bench_params *p = data->params;
	union bench_clock start, end, diff;
	mmap_op_t fn = r->fn.mmap_op;
	bool populate = strcmp(r->name, "populate") == 0;
	void *dst;

	if (data->seed)
		srand(data->seed);

	for (unsigned int i = 0; i < p->nr_loops; i++) {
		clock_get(&start);
		dst = bench_mmap(p->size, populate, p->page_shift);
		if (!dst)
			goto out;

		fn(dst, p->size, p->page_shift, p->seed);
		clock_get(&end);
		diff = clock_diff(&start, &end);
		clock_accum(&data->result, &diff);

		bench_munmap(dst, p->size);
	}

	return data;
out:
	data->error = -ENOMEM;
	return NULL;
}

static int do_mmap(const struct function *r, struct bench_params *p,
		  void *src __maybe_unused, void *dst __maybe_unused,
		  union bench_clock *accum)
{
	struct mmap_data *data;
	int error = 0;

	data = calloc(nr_threads, sizeof(*data));
	if (!data) {
		printf("# Failed to allocate thread resources\n");
		return -1;
	}

	for (unsigned int i = 0; i < nr_threads; i++) {
		data[i].func = r;
		data[i].params = p;
		if (p->seed)
			data[i].seed = p->seed + i;

		if (pthread_create(&data[i].id, NULL, do_mmap_thread, &data[i]) < 0)
			data[i].error = -errno;
	}

	for (unsigned int i = 0; i < nr_threads; i++) {
		union bench_clock *t = &data[i].result;

		pthread_join(data[i].id, NULL);

		clock_accum(accum, t);
		if (use_cycles)
			update_stats(&stats, t->cycles);
		else
			update_stats(&stats, t->tv.tv_sec * 1e6 + t->tv.tv_usec);
		error |= data[i].error;
	}
	free(data);

	if (error) {
		printf("# Memory allocation failed - maybe size (%s) %s?\n", size_str,
		       p->page_shift != PAGE_SHIFT_4KB ? "has insufficient hugepages" : "is too large");
	}
	return error ? -1 : 0;
}

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

static const struct function mmap_functions[] = {
	{ .name		= "demand",
	  .desc		= "Demand loaded mmap()",
	  .fn.mmap_op	= mmap_page_touch },

	{ .name		= "populate",
	  .desc		= "Eagerly populated mmap()",
	  .fn.mmap_op	= mmap_page_touch },

	{ .name = NULL, }
};

int bench_mem_mmap(int argc, const char **argv)
{
	static const struct option bench_mmap_options[] = {
		OPT_UINTEGER('r', "randomize", &seed,
			    "Seed to randomize page access offset."),
		OPT_UINTEGER('t', "threads", &nr_threads,
			    "Number of threads to run concurrently (default: 1)."),
		OPT_PARENT(bench_common_options),
		OPT_END()
	};

	struct bench_mem_info info = {
		.functions		= mmap_functions,
		.do_op			= do_mmap,
		.usage			= bench_mem_mmap_usage,
		.options		= bench_mmap_options,
	};

	return bench_mem_common(argc, argv, &info);
}
