/*
 * Copyright (c) 2008 Travis Geiselbrecht
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files
 * (the "Software"), to deal in the Software without restriction,
 * including without limitation the rights to use, copy, modify, merge,
 * publish, distribute, sublicense, and/or sell copies of the Software,
 * and to permit persons to whom the Software is furnished to do so,
 * subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
#include <debug.h>
#include <string.h>
#include <malloc.h>
#include <platform.h>
#include <kernel/thread.h>

static uint8_t *src;
static uint8_t *dst;

static uint8_t *src2;
static uint8_t *dst2;

#define BUFFER_SIZE (1024*1024)
#define ITERATIONS 16

extern void *mymemcpy(void *dst, const void *src, size_t len);
extern void *mymemset(void *dst, int c, size_t len);

static void *null_memcpy(void *dst, const void *src, size_t len)
{
	return dst;
}

static time_t bench_memcpy_routine(void *memcpy_routine(void *, const void *, size_t), size_t srcalign, size_t dstalign)
{
	int i;
	time_t t0;

	t0 = current_time();
	for (i=0; i < ITERATIONS; i++) {
		memcpy_routine(dst + dstalign, src + srcalign, BUFFER_SIZE);
	}
	return current_time() - t0;
}

static void bench_memcpy(void)
{
	time_t null, libc, mine;
	size_t srcalign, dstalign;
	
	printf("memcpy speed test\n");
	thread_sleep(200); // let the debug string clear the serial port

	for (srcalign = 0; srcalign < 64; ) {
		for (dstalign = 0; dstalign < 64; ) {

			null = bench_memcpy_routine(&null_memcpy, srcalign, dstalign);
			libc = bench_memcpy_routine(&memcpy, srcalign, dstalign);
			mine = bench_memcpy_routine(&mymemcpy, srcalign, dstalign);

			printf("srcalign %lu, dstalign %lu\n", srcalign, dstalign);
			printf("   null memcpy %u msecs\n", null);
			printf("   libc memcpy %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
			printf("   my   memcpy %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine);

			if (dstalign == 0)
				dstalign = 1;
			else 
				dstalign <<= 1;
		}
		if (srcalign == 0)
			srcalign = 1;
		else 
			srcalign <<= 1;
	}
}

static void fillbuf(void *ptr, size_t len, uint32_t seed)
{
	size_t i;

	for (i = 0; i < len; i++) {
		((char *)ptr)[i] = seed;
		seed *= 0x1234567;
	}
}

static void validate_memcpy(void)
{
	size_t srcalign, dstalign, size;
	const size_t maxsize = 256;

	printf("testing memcpy for correctness\n");

	/*
	 * do the simple tests to make sure that memcpy doesn't color outside
	 * the lines for all alignment cases
	 */
	for (srcalign = 0; srcalign < 64; srcalign++) {
		for (dstalign = 0; dstalign < 64; dstalign++) {
//			printf("srcalign %zu, dstalign %zu\n", srcalign, dstalign);
			for (size = 0; size < maxsize; size++) {

//				printf("srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size);

				fillbuf(src, maxsize * 2, 567);
				fillbuf(src2, maxsize * 2, 567);
				fillbuf(dst, maxsize * 2, 123514);
				fillbuf(dst2, maxsize * 2, 123514);

				memcpy(dst + dstalign, src + srcalign, size);
				mymemcpy(dst2 + dstalign, src2 + srcalign, size);

				int comp = memcmp(dst, dst2, maxsize * 2);
				if (comp != 0) {
					printf("error! srcalign %zu, dstalign %zu, size %zu\n", srcalign, dstalign, size);
				}
			}
		}
	}
}

static time_t bench_memset_routine(void *memset_routine(void *, int, size_t), size_t dstalign)
{
	int i;
	time_t t0;

	t0 = current_time();
	for (i=0; i < ITERATIONS; i++) {
		memset_routine(dst + dstalign, 0, BUFFER_SIZE);
	}
	return current_time() - t0;
}

static void bench_memset(void)
{
	time_t libc, mine;
	size_t dstalign;
	
	printf("memset speed test\n");
	thread_sleep(200); // let the debug string clear the serial port

	for (dstalign = 0; dstalign < 64; dstalign++) {

		libc = bench_memset_routine(&memset, dstalign);
		mine = bench_memset_routine(&mymemset, dstalign);

		printf("dstalign %lu\n", dstalign);
		printf("   libc memset %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
		printf("   my   memset %u msecs, %llu bytes/sec\n", mine, BUFFER_SIZE * ITERATIONS * 1000ULL / mine);
	}
}

static void validate_memset(void)
{
	size_t dstalign, size;
	int c;
	const size_t maxsize = 256;

	printf("testing memset for correctness\n");

	for (dstalign = 0; dstalign < 64; dstalign++) {
		printf("align %zd\n", dstalign);
		for (size = 0; size < maxsize; size++) {
			for (c = 0; c < 256; c++) {

				fillbuf(dst, maxsize * 2, 123514);
				fillbuf(dst2, maxsize * 2, 123514);

				memset(dst + dstalign, c, size);
				mymemset(dst2 + dstalign, c, size);

				int comp = memcmp(dst, dst2, maxsize * 2);
				if (comp != 0) {
					printf("error! align %zu, c %d, size %zu\n", dstalign, c, size);
				}
			}
		}
	}
}

#if defined(WITH_LIB_CONSOLE)
#include <lib/console.h>

static int string_tests(int argc, cmd_args *argv)
{
	src = memalign(64, BUFFER_SIZE + 256);
	dst = memalign(64, BUFFER_SIZE + 256);
	src2 = memalign(64, BUFFER_SIZE + 256);
	dst2 = memalign(64, BUFFER_SIZE + 256);

	printf("src %p, dst %p\n", src, dst);
	printf("src2 %p, dst2 %p\n", src2, dst2);

	if (argc < 3) {
		printf("not enough arguments:\n");
usage:
		printf("%s validate <routine>\n", argv[0].str);
		printf("%s bench <routine>\n", argv[0].str);
		goto out;
	}

	if (!strcmp(argv[1].str, "validate")) {
		if (!strcmp(argv[2].str, "memcpy")) {
			validate_memcpy();
		} else if (!strcmp(argv[2].str, "memset")) {
			validate_memset();
		}
	} else if (!strcmp(argv[1].str, "bench")) {
		if (!strcmp(argv[2].str, "memcpy")) {
			bench_memcpy();
		} else if (!strcmp(argv[2].str, "memset")) {
			bench_memset();
		}
	} else {
		goto usage;
	}

out:
	free(src);
	free(dst);
	free(src2);
	free(dst2);

	return 0;
}

STATIC_COMMAND_START
{ "string", NULL, &string_tests },
STATIC_COMMAND_END(stringtests);

#endif

