/*
 * Copyright(c) 2015 Toshi Kani, Hewlett Packard Enterprise. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of version 2 of the GNU General Public License as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/time.h>
#include <string.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

#define MiB(a)           ((a) * 1024UL * 1024UL)

static struct timeval start_tv, stop_tv;

// Calculate the difference between two time values.
static void tvsub(struct timeval *tdiff, struct timeval *t1, struct timeval *t0)
{
	tdiff->tv_sec = t1->tv_sec - t0->tv_sec;
	tdiff->tv_usec = t1->tv_usec - t0->tv_usec;
	if (tdiff->tv_usec < 0)
		tdiff->tv_sec--, tdiff->tv_usec += 1000000;
}

// Start timing now.
static void start(void)
{
	(void) gettimeofday(&start_tv, (struct timezone *) 0);
}

// Stop timing and return real time in microseconds.
static unsigned long long stop(void)
{
	struct timeval tdiff;

	(void) gettimeofday(&stop_tv, (struct timezone *) 0);
	tvsub(&tdiff, &stop_tv, &start_tv);
	return (tdiff.tv_sec * 1000000 + tdiff.tv_usec);
}

static void test_write(unsigned long *p, size_t size)
{
	size_t i;
	unsigned long *wp;
	unsigned long long timeval;

	start();
	for (i=0, wp=p; i<(size/sizeof(*wp)); i++)
		*wp++ = 1;
	timeval = stop();
	printf("Write: %10llu usec\n", timeval);
}

static void test_read(unsigned long *p, size_t size)
{
	size_t i;
	volatile unsigned long *wp, tmp;
	unsigned long long timeval;

	start();
	for (i=0, wp=p; i<(size/sizeof(*wp)); i++)
		tmp = *wp++;
	tmp = tmp;
	timeval = stop();
	printf("Read : %10llu usec\n", timeval);
}

int main(int argc, char **argv)
{
	int fd, i, opt, ret;
	int oflags, mprot, mflags = 0;
	int is_read_only = 0, is_mlock = 0, is_mlockall = 0;
	int mlock_skip = 0, read_test = 0, write_test = 0;
	void *mptr = NULL;
	unsigned long *p;
	struct stat stat;
	size_t size, cpy_size;
	const char *file_name = NULL;

	while ((opt = getopt(argc, argv, "RMSApsrw")) != -1) {
		switch (opt) {
			case 'R':
				printf("> mmap: read-only\n");
				is_read_only = 1;
				break;
			case 'M':
				printf("> mlock\n");
				is_mlock = 1;
				break;
			case 'S':
				printf("> mlock - skip first iteration\n");
				mlock_skip = 1;
				break;
			case 'A':
				printf("> mlockall\n");
				is_mlockall = 1;
				break;
			case 'p':
				printf("> MAP_POPULATE\n");
				mflags |= MAP_POPULATE;
				break;
			case 's':
				printf("> MAP_SHARED\n");
				mflags |= MAP_SHARED;
				break;
			case 'r':
				printf("> read-test\n");
				read_test = 1;
				break;
			case 'w':
				printf("> write-test\n");
				write_test = 1;
				break;
		}
	}

	if (optind == argc) {
		printf("missing file name\n");
		return EXIT_FAILURE;
	}
	file_name = argv[optind];

	if (!(mflags & MAP_SHARED)) {
		printf("> MAP_PRIVATE\n");
		mflags |= MAP_PRIVATE;
	}

	if (is_read_only) {
		oflags = O_RDONLY;
		mprot = PROT_READ;
	} else {
		oflags = O_RDWR;
		mprot = PROT_READ|PROT_WRITE;
	}

	fd = open(file_name, oflags);
	if (fd == -1) {
		perror("open failed");
		return EXIT_FAILURE;
	}

	ret = fstat(fd, &stat);
	if (ret < 0) {
		perror("fstat failed");
		return EXIT_FAILURE;
	}
	size = stat.st_size;

	printf("> open %s size %#zx flags %#x\n", file_name, size, oflags);

	ret = posix_memalign(&mptr, MiB(2), size);
	if (ret ==0)
		free(mptr);

	printf("> mmap mprot 0x%x flags 0x%x\n", mprot, mflags);
	p = mmap(mptr, size, mprot, mflags, fd, 0x0);
	if (!p) {
		perror("mmap failed");
		return EXIT_FAILURE;
	}
	if ((long unsigned)p & (MiB(2)-1))
		printf("> mmap: NOT 2MiB aligned: 0x%p\n", p);
	else
		printf("> mmap: 2MiB aligned: 0x%p\n", p);

	cpy_size = size;

	for (i=0; i<3; i++) {

		if (is_mlock && !mlock_skip) {
			printf("> mlock 0x%p\n", p);
			ret = mlock(p, size);
			if (ret < 0) {
				perror("mlock failed");
				return EXIT_FAILURE;
			}
		} else if (is_mlockall) {
			printf("> mlockall\n");
			ret = mlockall(MCL_CURRENT|MCL_FUTURE);
			if (ret < 0) {
				perror("mlockall failed");
				return EXIT_FAILURE;
			}
		}

		printf("===== %d =====\n", i+1);
		if (write_test)
			test_write(p, cpy_size);
		if (read_test)
			test_read(p, cpy_size);

		if (is_mlock && !mlock_skip) {
			printf("> munlock 0x%p\n", p);
			ret = munlock(p, size);
			if (ret < 0) {
				perror("munlock failed");
				return EXIT_FAILURE;
			}
		} else if (is_mlockall) {
			printf("> munlockall\n");
			ret = munlockall();
			if (ret < 0) {
				perror("munlockall failed");
				return EXIT_FAILURE;
			}
		}

		/* skip, if requested, only the first iteration */
		mlock_skip = 0;
	}

	printf("> munmap 0x%p\n", p);
	munmap(p, size);
	return EXIT_SUCCESS;
}

