/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief CPU warm-up utility, used to counteract CPU throttling.
 *//*--------------------------------------------------------------------*/

#include "tcuCPUWarmup.hpp"
#include "deDefs.hpp"
#include "deMath.h"
#include "deClock.h"

#include <algorithm>

namespace tcu
{

namespace warmupCPUInternal
{

volatile Unused g_unused;

};

template <typename T, int Size>
static inline float floatMedian (const T (&v)[Size])
{
	T temp[Size];
	for (int i = 0; i < Size; i++)
		temp[i] = v[i];

	std::sort(DE_ARRAY_BEGIN(temp), DE_ARRAY_END(temp));

	return Size % 2 == 0
		   ? 0.5f * ((float)temp[Size/2-1] + (float)temp[Size/2])
		   : (float)temp[Size/2];
}

template <typename T, int Size>
static inline float floatRelativeMedianAbsoluteDeviation (const T (&v)[Size])
{
	const float		median = floatMedian(v);
	float			absoluteDeviations[Size];

	for (int i = 0; i < Size; i++)
		absoluteDeviations[i] = deFloatAbs((float)v[i] - median);

	return floatMedian(absoluteDeviations) / median;
}

static inline float unusedComputation (float initial, int numIterations)
{
	float	a = initial;
	int		b = 123;

	for (int i = 0; i < numIterations; i++)
	{
		// Arbitrary computations.
		for (int j = 0; j < 4; j++)
		{
			a = deFloatCos(a + (float)b);
			b = (b + 63) % 107 + de::abs((int)(a*10.0f));
		}
	}

	return a + (float)b;
}

void warmupCPU (void)
{
	float	unused				= *warmupCPUInternal::g_unused.m_v;
	int		computationSize		= 1;

	// Do a rough calibration for computationSize to get unusedComputation's running time above a certain threshold.
	while (computationSize < 1<<30) // \note This condition is unlikely to be met. The "real" loop exit is the break below.
	{
		const float		singleMeasurementThreshold	= 10000.0f;
		const int		numMeasurements				= 3;
		deInt64			times[numMeasurements];

		for (int i = 0; i < numMeasurements; i++)
		{
			const deUint64 startTime = deGetMicroseconds();
			unused = unusedComputation(unused, computationSize);
			times[i] = (deInt64)(deGetMicroseconds() - startTime);
		}

		if (floatMedian(times) >= singleMeasurementThreshold)
			break;

		computationSize *= 2;
	}

	// Do unusedComputations until running time seems stable enough.
	{
		const int			maxNumMeasurements							= 50;
		const int			numConsecutiveMeasurementsRequired			= 5;
		const float			relativeMedianAbsoluteDeviationThreshold	= 0.05f;
		deInt64				latestTimes[numConsecutiveMeasurementsRequired];

		for (int measurementNdx = 0;

			 measurementNdx < maxNumMeasurements &&
			 (measurementNdx < numConsecutiveMeasurementsRequired ||
			  floatRelativeMedianAbsoluteDeviation(latestTimes) > relativeMedianAbsoluteDeviationThreshold);

			 measurementNdx++)
		{
			const deUint64 startTime = deGetMicroseconds();
			unused = unusedComputation(unused, computationSize);
			latestTimes[measurementNdx % numConsecutiveMeasurementsRequired] = (deInt64)(deGetMicroseconds() - startTime);
		}
	}

	*warmupCPUInternal::g_unused.m_v = unused;
}

} // tcu
