/* Copyright (c) 2015 Google Inc
 * Davide Libenzi <dlibenzi@google.com>
 * See LICENSE for details.
 */

#include <ros/arch/arch.h>
#include <ros/common.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <parlib/parlib.h>
#include <parlib/core_set.h>
#include <parlib/stdio.h>

static const unsigned int llcores[] = {
	0
};

void parlib_get_ll_core_set(struct core_set *cores)
{
	parlib_get_none_core_set(cores);
	for (size_t i = 0; i < COUNT_OF(llcores); i++)
		parlib_set_core(cores, llcores[i]);
}

size_t parlib_nr_ll_cores(void)
{
	return COUNT_OF(llcores);
}

static int guess_nr_cores(void)
{
	return max_vcores() + parlib_nr_ll_cores();
}

static int get_vars_nr_cores(void)
{
	int fd, ret;
	char buf[10];

	fd = open("#vars/num_cores!dw", O_READ);
	if (fd < 0)
		return -1;
	if (read(fd, buf, sizeof(buf)) <= 0) {
		close(fd);
		return -1;
	}
	ret = atoi(buf);
	return ret;
}

static int nr_cores;

static void set_nr_cores(void *arg)
{
	nr_cores = get_vars_nr_cores();
	if (nr_cores == -1)
		nr_cores = guess_nr_cores();
}

size_t parlib_nr_total_cores(void)
{
	static parlib_once_t once = PARLIB_ONCE_INIT;

	parlib_run_once(&once, set_nr_cores, NULL);
	return nr_cores;
}

void parlib_parse_cores(const char *str, struct core_set *cores)
{
	unsigned int fcpu, ncpu;
	char *dstr = strdup(str);
	char *sptr = NULL;
	char *tok, *sptr2;

	if (!dstr) {
		perror("Duplicating a string");
		exit(1);
	}
	ZERO_DATA(*cores);
	for (tok = strtok_r(dstr, ",", &sptr); tok;
		 tok = strtok_r(NULL, ",", &sptr)) {

		if (strchr(tok, '-')) {
			if (sscanf(tok, "%u-%u", &fcpu, &ncpu) != 2) {
				fprintf(stderr, "Invalid CPU range: %s\n", tok);
				exit(1);
			}
			if (fcpu >= parlib_nr_total_cores()) {
				fprintf(stderr, "CPU number out of bound: %u\n",
					fcpu);
				exit(1);
			}
			if (ncpu >= parlib_nr_total_cores()) {
				fprintf(stderr, "CPU number out of bound: %u\n",
					ncpu);
				exit(1);
			}
			if (fcpu > ncpu) {
				fprintf(stderr,
					"CPU range is backwards: %u-%u\n",
					fcpu, ncpu);
				exit(1);
			}
			for (; fcpu <= ncpu; fcpu++)
				parlib_set_core(cores, fcpu);
		} else {
			fcpu = atoi(tok);
			if (fcpu >= parlib_nr_total_cores()) {
				fprintf(stderr, "CPU number out of bound: %u\n",
					fcpu);
				exit(1);
			}
			parlib_set_core(cores, fcpu);
		}
	}
	free(dstr);
}

void parlib_get_all_core_set(struct core_set *cores)
{
	size_t max_cores = parlib_nr_total_cores();

	memset(cores->core_set, 0xff, DIV_ROUND_UP(max_cores, CHAR_BIT));
}

void parlib_get_none_core_set(struct core_set *cores)
{
	size_t max_cores = parlib_nr_total_cores();

	memset(cores->core_set, 0, DIV_ROUND_UP(max_cores, CHAR_BIT));
}

void parlib_not_core_set(struct core_set *dcs)
{
	size_t max_cores = parlib_nr_total_cores();

	for (size_t i = 0; (max_cores > 0) && (i < sizeof(dcs->core_set)); i++)
	{
		size_t nb = (max_cores >= CHAR_BIT) ? CHAR_BIT : max_cores;

		dcs->core_set[i] = (~dcs->core_set[i]) & ((1 << nb) - 1);
		max_cores -= nb;
	}
}

void parlib_and_core_sets(struct core_set *dcs, const struct core_set *scs)
{
	for (size_t i = 0; i < sizeof(dcs->core_set); i++)
		dcs->core_set[i] &= scs->core_set[i];
}

void parlib_or_core_sets(struct core_set *dcs, const struct core_set *scs)
{
	for (size_t i = 0; i < sizeof(dcs->core_set); i++)
		dcs->core_set[i] |= scs->core_set[i];
}
