/*
 * 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;
	
	dprintf("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);

			dprintf("srcalign %lu, dstalign %lu\n", srcalign, dstalign);
			dprintf("   null memcpy %u msecs\n", null);
			dprintf("   libc memcpy %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
			dprintf("   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;

	dprintf("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++) {
//			dprintf("srcalign %zu, dstalign %zu\n", srcalign, dstalign);
			for (size = 0; size < maxsize; size++) {

//				dprintf("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) {
					dprintf("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;
	
	dprintf("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);

		dprintf("dstalign %lu\n", dstalign);
		dprintf("   libc memset %u msecs, %llu bytes/sec\n", libc, BUFFER_SIZE * ITERATIONS * 1000ULL / libc);
		dprintf("   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;

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

	for (dstalign = 0; dstalign < 64; dstalign++) {
		dprintf("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) {
					dprintf("error! align %zu, c %d, size %zu\n", dstalign, c, size);
				}
			}
		}
	}
}

#if defined(WITH_APP_CONSOLE)
#include <app/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);

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

	if (argc < 3) {
		dprintf("not enough arguments:\n");
usage:
		dprintf("%s validate <routine>\n", argv[0].str);
		dprintf("%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

