/*
 *heat_cpu.c
 *
 * Copyright (C) 2011, Linaro Limited.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston,
 * MA  02110-1301, USA.
 *
 * Contributors:
 *	Robert Lee <rob.lee@linaro.org>
 *	Amit Daniel <amit.kachhap@linaro.org>
 *	VERSION=0.4
 */

/*
 * program to heat up your cpus
 *
 * Creates a thread for each cpu which will run in a loop that executes
 * code that (hopefully) produces a large amount of heat.
 *
 * The each thread's policy is set to make it very low priority.  This allows
 * this script to be ran in conjunction with other code that may want to run
 * and exercise (produce heat) from other various parts of the SoC such
 * as the GPU and VPU.
 */


#define _GNU_SOURCE

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
#include <string.h>
#include <math.h>

#define NR_THREAD 3

int cont = 1;
int cpu_index;

long long a = 1, c = 1;
float f = M_PI;
pid_t thr_id[NR_THREAD];
int moderate_inst;


#ifdef ANDROID
int                 conditionMet;
pthread_cond_t      cond  = PTHREAD_COND_INITIALIZER;
pthread_mutex_t     mutex = PTHREAD_MUTEX_INITIALIZER;
#endif

void *do_loop(void *data)
{
	const long long b = 3;
	float f = 1.12;

	a = 1;
	c = 1;
#ifdef ANDROID
	long int thread = (long int) data;
	thr_id[thread] = gettid();
	pthread_mutex_lock(&mutex);
	while (!conditionMet)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);
#endif

	while (cont) {
		if (!moderate_inst) {
			a += a * b;
			c += c * b;
			f += f * b;
		} else {
			a += 1;
		}
	}

	return 0;
}

int main(int arg_count, char *argv[])
{
	int ret, i;
	int num_cpus = sysconf(_SC_NPROCESSORS_ONLN);
	cpu_set_t cpuset;

	printf("Num CPUs: %d\n", num_cpus);
	if (arg_count > 1) {
		if (!strcmp("moderate", argv[1])) {
			moderate_inst = 1;
			printf("use moderate heating\n");
		}
	}

	/* clear out cpus */
	CPU_ZERO(&cpuset);

	/* Create a pthread_attr_t object for each core */
	pthread_attr_t *p = (pthread_attr_t *) malloc(
				num_cpus * sizeof(pthread_attr_t));

	if (!p) {
		printf("ERROR: out of memory\n");
		return -1;
	}

	pthread_t *p_thread_ptr = (pthread_t *) malloc(
					num_cpus * sizeof(pthread_attr_t));

	if (!p_thread_ptr) {
		printf("ERROR: out of memory\n");
		return -1;
	}

	for (i = 0; i < num_cpus; i++) {
		ret = pthread_attr_init(&p[i]);

		if (ret) {
			printf("Error initializing pattr\n");
			return ret;
		}
#ifndef ANDROID
		/* Make workload thread's very low priority if allowed*/
#ifdef SCHED_IDLE
		ret = pthread_attr_setschedpolicy(&p[i], SCHED_IDLE);
#endif

#else
		ret = pthread_attr_setschedpolicy(&p[i], SCHED_NORMAL);
#endif
		/* for each new object */
		CPU_SET(i, &cpuset);
#ifndef ANDROID
		ret = pthread_attr_setaffinity_np(&p[i],
					sizeof(cpu_set_t), &cpuset);

		if (ret) {
			printf("Error setting affinity on pthread attribute\n");
			printf("i: %i\n", i);
			printf("Error: %s\n", strerror(ret));
			return ret;
		}
#endif
	CPU_CLR(i, &cpuset);

	}

	for (i = 0; i < num_cpus; i++) {
		/* create a new thread that will execute 'do_loop()' */
		ret = pthread_create(&p_thread_ptr[i], &p[i],
							do_loop, (void *)i);
		if (ret < 0)
			printf("Error setting affinity for cpu%d\n", i);

#ifdef ANDROID
		CPU_ZERO(&cpuset);
		CPU_SET(i, &cpuset);

		ret = sched_setaffinity(thr_id[i], sizeof(cpuset), &cpuset);
		if (ret) {
			printf("Error setting affinity on pthread th_id\n");
			printf("Error: %s\n", strerror(ret));
			return ret;
		}
#endif
	}

#ifdef ANDROID
	pthread_mutex_lock(&mutex);
	conditionMet = 1;
	pthread_cond_broadcast(&cond);
	pthread_mutex_unlock(&mutex);
#endif

	while (1)
		sleep(1);
	return 0;
}
