// SPDX-License-Identifier: GPL-2.0
/*
 * fill_buf benchmark
 *
 * Copyright (C) 2018 Intel Corporation
 *
 * Authors:
 *    Sai Praneeth Prakhya <sai.praneeth.prakhya@intel.com>,
 *    Fenghua Yu <fenghua.yu@intel.com>
 */
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <inttypes.h>
#include <malloc.h>
#include <string.h>

#include "resctrl.h"

#define CL_SIZE			(64)
#define PAGE_SIZE		(4 * 1024)
#define MB			(1024 * 1024)

static unsigned char *startptr;

static void sb(void)
{
#if defined(__i386) || defined(__x86_64)
	asm volatile("sfence\n\t"
		     : : : "memory");
#endif
}

static void ctrl_handler(int signo)
{
	free(startptr);
	printf("\nEnding\n");
	sb();
	exit(EXIT_SUCCESS);
}

static void cl_flush(void *p)
{
#if defined(__i386) || defined(__x86_64)
	asm volatile("clflush (%0)\n\t"
		     : : "r"(p) : "memory");
#endif
}

static void mem_flush(void *p, size_t s)
{
	char *cp = (char *)p;
	size_t i = 0;

	s = s / CL_SIZE; /* mem size in cache llines */

	for (i = 0; i < s; i++)
		cl_flush(&cp[i * CL_SIZE]);

	sb();
}

static void *malloc_and_init_memory(size_t s)
{
	uint64_t *p64;
	size_t s64;

	void *p = memalign(PAGE_SIZE, s);

	p64 = (uint64_t *)p;
	s64 = s / sizeof(uint64_t);

	while (s64 > 0) {
		*p64 = (uint64_t)rand();
		p64 += (CL_SIZE / sizeof(uint64_t));
		s64 -= (CL_SIZE / sizeof(uint64_t));
	}

	return p;
}

static int fill_one_span_read(unsigned char *start_ptr, unsigned char *end_ptr)
{
	unsigned char sum, *p;

	sum = 0;
	p = start_ptr;
	while (p < end_ptr) {
		sum += *p;
		p += (CL_SIZE / 2);
	}

	return sum;
}

static
void fill_one_span_write(unsigned char *start_ptr, unsigned char *end_ptr)
{
	unsigned char *p;

	p = start_ptr;
	while (p < end_ptr) {
		*p = '1';
		p += (CL_SIZE / 2);
	}
}

static int fill_cache_read(unsigned char *start_ptr, unsigned char *end_ptr,
			   char *resctrl_val)
{
	int ret = 0;
	FILE *fp;

	while (1) {
		ret = fill_one_span_read(start_ptr, end_ptr);
		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
			break;
	}

	/* Consume read result so that reading memory is not optimized out. */
	fp = fopen("/dev/null", "w");
	if (!fp)
		perror("Unable to write to /dev/null");
	fprintf(fp, "Sum: %d ", ret);
	fclose(fp);

	return 0;
}

static int fill_cache_write(unsigned char *start_ptr, unsigned char *end_ptr,
			    char *resctrl_val)
{
	while (1) {
		fill_one_span_write(start_ptr, end_ptr);
		if (!strncmp(resctrl_val, CAT_STR, sizeof(CAT_STR)))
			break;
	}

	return 0;
}

static int
fill_cache(unsigned long long buf_size, int malloc_and_init, int memflush,
	   int op, char *resctrl_val)
{
	unsigned char *start_ptr, *end_ptr;
	unsigned long long i;
	int ret;

	if (malloc_and_init)
		start_ptr = malloc_and_init_memory(buf_size);
	else
		start_ptr = malloc(buf_size);

	if (!start_ptr)
		return -1;

	startptr = start_ptr;
	end_ptr = start_ptr + buf_size;

	/*
	 * It's better to touch the memory once to avoid any compiler
	 * optimizations
	 */
	if (!malloc_and_init) {
		for (i = 0; i < buf_size; i++)
			*start_ptr++ = (unsigned char)rand();
	}

	start_ptr = startptr;

	/* Flush the memory before using to avoid "cache hot pages" effect */
	if (memflush)
		mem_flush(start_ptr, buf_size);

	if (op == 0)
		ret = fill_cache_read(start_ptr, end_ptr, resctrl_val);
	else
		ret = fill_cache_write(start_ptr, end_ptr, resctrl_val);

	if (ret) {
		printf("\n Error in fill cache read/write...\n");
		return -1;
	}

	free(startptr);

	return 0;
}

int run_fill_buf(unsigned long span, int malloc_and_init_memory,
		 int memflush, int op, char *resctrl_val)
{
	unsigned long long cache_size = span;
	int ret;

	/* set up ctrl-c handler */
	if (signal(SIGINT, ctrl_handler) == SIG_ERR)
		printf("Failed to catch SIGINT!\n");
	if (signal(SIGHUP, ctrl_handler) == SIG_ERR)
		printf("Failed to catch SIGHUP!\n");

	ret = fill_cache(cache_size, malloc_and_init_memory, memflush, op,
			 resctrl_val);
	if (ret) {
		printf("\n Error in fill cache\n");
		return -1;
	}

	return 0;
}
