/* 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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <parlib/parlib.h>
#include <parlib/core_set.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];
}
