#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>

/*
 * gcc -O3 -Wall -std=c99 -pedantic malloc.c -static -o malloc
 *
 */

int main (int argc, char *argv[])
{
	size_t		size	= 0;
	char		*data	= NULL;
	time_t		t_start, t_end;
	size_t		exp;

	if (argc != 2) {
		printf ("Usage: %s MemorySize[kmg]\n", argv[0]);
		return 1;
	}

	size = 0;
	exp = 1;
	for (data = argv[1]; *data; ++data) {
		switch (*data) {
		case '0': case '1': case '2': case '3':
		case '4': case '5': case '6': case '7':
		case '8': case '9':
			size += (*data - '0');
			size *= exp;
			exp *= 10;
			break;
		case 'B': case 'b':
			break;
		case 'K':
			size *= 1000;
			break;
		case 'k':
			size *= 1024;
			break;
		case 'M':
			size *= 1000 * 1000;
			break;
		case 'm':
			size *= 1024 * 1024;
			break;
		case 'G':
			size *= 1000 * 1000 * 1000;
			break;
		case 'g':
			size *= 1024 * 1024 * 1024;
			break;
		default:
			printf ("Unhandled Character '%c' in Arg1.\n",
					*data);
			return -1;
		}
	}
	data = NULL;

	printf ("Allocating %zu bytes...\n", size);

	t_start = time(NULL);

	data = malloc(size);
	if (NULL == data) {
		int	err = errno;
		printf ("Unable to allocate %zu bytes: %s\n",
				size,
				strerror(err));
		return -1;
	}

	t_end = time(NULL);

	printf ("%zu bytes allocated (errno=%d) (Duration=%lus).\n"
		"Hit Return to continue writing the memory.\n",
		size, errno, t_end - t_start);

	(void) getc(stdin);

	errno = 0;

	t_start = time(NULL);

	(void) memset (data, 0, size);

	t_end = time(NULL);

	printf ("Wrote %zu bytes (errno=%d) (Duration=%lus).\n"
		"Hit Return to continue freeing the memory.\n",
		size, errno, t_end - t_start);

	(void) getc(stdin);

	errno = 0;

	t_start = time(NULL);

	free (data);

	t_end = time(NULL);

	printf ("%zu bytes free'd (errno=%d) (Duration=%lus).\n"
		"Hit Return to Quit.\n",
		size, errno, t_end - t_start);

	(void) getc(stdin);

	return 0;
}
