/*
 * 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 <app.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 void validate_memcpy_overlap(void)
{
	size_t srcalign, dstalign, size;
	const size_t maxsize = 256;
	int comp;

	printf("testing memcpy for correctness in overlap cases\n");

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

			fillbuf(src, maxsize * 2, 567);
			fillbuf(src2, maxsize * 2, 567);

			/* Case one will check cpy memory is the same - fwd*/
			memcpy(src + dstalign, src, size);
			comp = memcmp(src + dstalign, src2, size);
			if (comp != 0) {
				printf("ERROR (Case1): dstalign %zu, size %zu, ret %d\n", dstalign, size, comp);
			}

			fillbuf(src, maxsize * 2, 8588485);
			fillbuf(src2, maxsize * 2, 8588485);

			/* Case two will check cpy memory is the same - bkwd*/
			memcpy(src, src + dstalign, size);
			comp = memcmp(src, src2 + dstalign, size);
			if (comp != 0) {
				printf("ERROR (Case2): dstalign %zu, size %zu, ret %d\n", dstalign, size, comp);
			}
		}
	}
}

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[2].str, "memcpy_overlap")) {
			validate_memcpy_overlap();
		}
	} 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

APP_START(stringtests)
APP_END

