/*  cpufreq-bench CPUFreq microbenchmark
 *
 *  Copyright (C) 2008 Christian Kornacker <ckornacker@suse.de>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  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.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#include <stdio.h>
#include <unistd.h>
#include <math.h>

#include "config.h"
#include "system.h"
#include "benchmark.h"

/* Print out progress if we log into a file */
#define show_progress(total_time, progress_time)	\
if (config->output != stdout) {				\
	fprintf(stdout, "Progress: %02lu %%\r",		\
		(progress_time * 100) / total_time);	\
	fflush(stdout);					\
}

/**
 * compute how many rounds of calculation we should do
 * to get the given load time
 *
 * @param load aimed load time in µs
 *
 * @retval rounds of calculation
 **/

unsigned int calculate_timespace(long load, struct config *config)
{
	int i;
	long long now, then;
	unsigned int estimated = GAUGECOUNT;
	unsigned int rounds = 0;
	unsigned int timed = 0;

	if (config->verbose)
		printf("calibrating load of %lius, please wait...\n", load);

	/* get the initial calculation time for a specific number of rounds */
	now = get_time();
	ROUNDS(estimated);
	then = get_time();

	timed = (unsigned int)(then - now);

	/* approximation of the wanted load time by comparing with the
	 * initial calculation time */
	for (i = 0; i < 4; i++) {
		rounds = (unsigned int)(load * estimated / timed);
		dprintf("calibrating with %u rounds\n", rounds);
		now = get_time();
		ROUNDS(rounds);
		then = get_time();

		timed = (unsigned int)(then - now);
		estimated = rounds;
	}
	if (config->verbose)
		printf("calibration done\n");

	return estimated;
}

/**
 * benchmark
 * generates a specific sleep an load time with the performance
 * governor and compares the used time for same calculations done
 * with the configured powersave governor
 *
 * @param config config values for the benchmark
 *
 **/

void start_benchmark(struct config *config)
{
	unsigned int _round, cycle;
	long long now, then;
	long sleep_time = 0, load_time = 0;
	long performance_time = 0, powersave_time = 0;
	unsigned int calculations;
	unsigned long total_time = 0, progress_time = 0;

	sleep_time = config->sleep;
	load_time = config->load;

	/* For the progress bar */
	for (_round = 1; _round <= config->rounds; _round++)
		total_time += _round * (config->sleep + config->load);
	total_time *= 2; /* powersave and performance cycles */

	for (_round = 0; _round < config->rounds; _round++) {
		performance_time = 0LL;
		powersave_time = 0LL;

		show_progress(total_time, progress_time);

		/* set the cpufreq governor to "performance" which disables
		 * P-State switching. */
		if (set_cpufreq_governor("performance", config->cpu) != 0)
			return;

		/* calibrate the calculation time. the resulting calculation
		 * _rounds should produce a load which matches the configured
		 * load time */
		calculations = calculate_timespace(load_time, config);

		if (config->verbose)
			printf("_round %i: doing %u cycles with %u calculations"
			       " for %lius\n", _round + 1, config->cycles,
			       calculations, load_time);

		fprintf(config->output, "%u %li %li ",
			_round, load_time, sleep_time);

		if (config->verbose)
			printf("average: %lius, rps:%li\n",
				load_time / calculations,
				1000000 * calculations / load_time);

		/* do some sleep/load cycles with the performance governor */
		for (cycle = 0; cycle < config->cycles; cycle++) {
			now = get_time();
			usleep(sleep_time);
			ROUNDS(calculations);
			then = get_time();
			performance_time += then - now - sleep_time;
			if (config->verbose)
				printf("performance cycle took %lius, "
					"sleep: %lius, "
					"load: %lius, rounds: %u\n",
					(long)(then - now), sleep_time,
					load_time, calculations);
		}
		fprintf(config->output, "%li ",
			performance_time / config->cycles);

		progress_time += sleep_time + load_time;
		show_progress(total_time, progress_time);

		/* set the powersave governor which activates P-State switching
		 * again */
		if (set_cpufreq_governor(config->governor, config->cpu) != 0)
			return;

		/* again, do some sleep/load cycles with the
		 * powersave governor */
		for (cycle = 0; cycle < config->cycles; cycle++) {
			now = get_time();
			usleep(sleep_time);
			ROUNDS(calculations);
			then = get_time();
			powersave_time += then - now - sleep_time;
			if (config->verbose)
				printf("powersave cycle took %lius, "
					"sleep: %lius, "
					"load: %lius, rounds: %u\n",
					(long)(then - now), sleep_time,
					load_time, calculations);
		}

		progress_time += sleep_time + load_time;

		/* compare the average sleep/load cycles  */
		fprintf(config->output, "%li ",
			powersave_time / config->cycles);
		fprintf(config->output, "%.3f\n",
			performance_time * 100.0 / powersave_time);
		fflush(config->output);

		if (config->verbose)
			printf("performance is at %.2f%%\n",
				performance_time * 100.0 / powersave_time);

		sleep_time += config->sleep_step;
		load_time += config->load_step;
	}
}
