// SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
/*
 * uprobe.c
 *
 * uprobe benchmarks
 *
 *  Copyright (C) 2023, Red Hat Inc, Arnaldo Carvalho de Melo <acme@redhat.com>
 */
#include "../perf.h"
#include "../util/util.h"
#include <subcmd/parse-options.h>
#include "../builtin.h"
#include "bench.h"
#include <linux/compiler.h>
#include <linux/time64.h>

#include <inttypes.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>
#include <stdlib.h>

#define LOOPS_DEFAULT 1000
static int loops = LOOPS_DEFAULT;

enum bench_uprobe {
	BENCH_UPROBE__BASELINE,
	BENCH_UPROBE__EMPTY,
	BENCH_UPROBE__TRACE_PRINTK,
	BENCH_UPROBE__EMPTY_RET,
	BENCH_UPROBE__TRACE_PRINTK_RET,
};

static const struct option options[] = {
	OPT_INTEGER('l', "loop",	&loops,		"Specify number of loops"),
	OPT_END()
};

static const char * const bench_uprobe_usage[] = {
	"perf bench uprobe <options>",
	NULL
};

#ifdef HAVE_BPF_SKEL
#include "bpf_skel/bench_uprobe.skel.h"

#define bench_uprobe__attach_uprobe(prog) \
	skel->links.prog = bpf_program__attach_uprobe_opts(/*prog=*/skel->progs.prog, \
							   /*pid=*/-1, \
							   /*binary_path=*/"libc.so.6", \
							   /*func_offset=*/0, \
							   /*opts=*/&uprobe_opts); \
	if (!skel->links.prog) { \
		err = -errno; \
		fprintf(stderr, "Failed to attach bench uprobe \"%s\": %m\n", #prog); \
		goto cleanup; \
	}

struct bench_uprobe_bpf *skel;

static int bench_uprobe__setup_bpf_skel(enum bench_uprobe bench)
{
	DECLARE_LIBBPF_OPTS(bpf_uprobe_opts, uprobe_opts);
	int err;

	/* Load and verify BPF application */
	skel = bench_uprobe_bpf__open();
	if (!skel) {
		fprintf(stderr, "Failed to open and load uprobes bench BPF skeleton\n");
		return -1;
	}

	err = bench_uprobe_bpf__load(skel);
	if (err) {
		fprintf(stderr, "Failed to load and verify BPF skeleton\n");
		goto cleanup;
	}

	uprobe_opts.func_name = "usleep";
	switch (bench) {
	case BENCH_UPROBE__BASELINE:							break;
	case BENCH_UPROBE__EMPTY:	 bench_uprobe__attach_uprobe(empty);		break;
	case BENCH_UPROBE__TRACE_PRINTK: bench_uprobe__attach_uprobe(trace_printk);	break;
	case BENCH_UPROBE__EMPTY_RET:	 bench_uprobe__attach_uprobe(empty_ret);	break;
	case BENCH_UPROBE__TRACE_PRINTK_RET: bench_uprobe__attach_uprobe(trace_printk_ret); break;
	default:
		fprintf(stderr, "Invalid bench: %d\n", bench);
		goto cleanup;
	}

	return err;
cleanup:
	bench_uprobe_bpf__destroy(skel);
	skel = NULL;
	return err;
}

static void bench_uprobe__teardown_bpf_skel(void)
{
	if (skel) {
		bench_uprobe_bpf__destroy(skel);
		skel = NULL;
	}
}
#else
static int bench_uprobe__setup_bpf_skel(enum bench_uprobe bench __maybe_unused) { return 0; }
static void bench_uprobe__teardown_bpf_skel(void) {};
#endif

static int bench_uprobe_format__default_fprintf(const char *name, const char *unit, u64 diff, FILE *fp)
{
	static u64 baseline, previous;
	s64 diff_to_baseline = diff - baseline,
	    diff_to_previous = diff - previous;
	int printed = fprintf(fp, "# Executed %'d %s calls\n", loops, name);

	printed += fprintf(fp, " %14s: %'" PRIu64 " %ss", "Total time", diff, unit);

	if (baseline) {
		printed += fprintf(fp, " %s%'" PRId64 " to baseline", diff_to_baseline > 0 ? "+" : "", diff_to_baseline);

		if (previous != baseline)
			fprintf(stdout, " %s%'" PRId64 " to previous", diff_to_previous > 0 ? "+" : "", diff_to_previous);
	}

	printed += fprintf(fp, "\n\n %'.3f %ss/op", (double)diff / (double)loops, unit);

	if (baseline) {
		printed += fprintf(fp, " %'.3f %ss/op to baseline", (double)diff_to_baseline / (double)loops, unit);

		if (previous != baseline)
			printed += fprintf(fp, " %'.3f %ss/op to previous", (double)diff_to_previous / (double)loops, unit);
	} else {
		baseline = diff;
	}

	fputc('\n', fp);

	previous = diff;

	return printed + 1;
}

static int bench_uprobe(int argc, const char **argv, enum bench_uprobe bench)
{
	const char *name = "usleep(1000)", *unit = "usec";
	struct timespec start, end;
	u64 diff;
	int i;

	argc = parse_options(argc, argv, options, bench_uprobe_usage, 0);

	if (bench != BENCH_UPROBE__BASELINE && bench_uprobe__setup_bpf_skel(bench) < 0)
		return 0;

        clock_gettime(CLOCK_REALTIME, &start);

	for (i = 0; i < loops; i++) {
		usleep(USEC_PER_MSEC);
	}

	clock_gettime(CLOCK_REALTIME, &end);

	diff = end.tv_sec * NSEC_PER_SEC + end.tv_nsec - (start.tv_sec * NSEC_PER_SEC + start.tv_nsec);
	diff /= NSEC_PER_USEC;

	switch (bench_format) {
	case BENCH_FORMAT_DEFAULT:
		bench_uprobe_format__default_fprintf(name, unit, diff, stdout);
		break;

	case BENCH_FORMAT_SIMPLE:
		printf("%" PRIu64 "\n", diff);
		break;

	default:
		/* reaching here is something of a disaster */
		fprintf(stderr, "Unknown format:%d\n", bench_format);
		exit(1);
	}

	if (bench != BENCH_UPROBE__BASELINE)
		bench_uprobe__teardown_bpf_skel();

	return 0;
}

int bench_uprobe_baseline(int argc, const char **argv)
{
	return bench_uprobe(argc, argv, BENCH_UPROBE__BASELINE);
}

int bench_uprobe_empty(int argc, const char **argv)
{
	return bench_uprobe(argc, argv, BENCH_UPROBE__EMPTY);
}

int bench_uprobe_trace_printk(int argc, const char **argv)
{
	return bench_uprobe(argc, argv, BENCH_UPROBE__TRACE_PRINTK);
}

int bench_uprobe_empty_ret(int argc, const char **argv)
{
	return bench_uprobe(argc, argv, BENCH_UPROBE__EMPTY_RET);
}

int bench_uprobe_trace_printk_ret(int argc, const char **argv)
{
	return bench_uprobe(argc, argv, BENCH_UPROBE__TRACE_PRINTK_RET);
}
