// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2021 Red Hat Inc, Daniel Bristot de Oliveira <bristot@kernel.org>
 */

#define _GNU_SOURCE
#ifdef HAVE_LIBCPUPOWER_SUPPORT
#include <cpuidle.h>
#endif /* HAVE_LIBCPUPOWER_SUPPORT */
#include <dirent.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <ctype.h>
#include <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <stdio.h>
#include <limits.h>

#include "common.h"

#define MAX_MSG_LENGTH	1024
bool config_debug;

/*
 * err_msg - print an error message to the stderr
 */
void err_msg(const char *fmt, ...)
{
	char message[MAX_MSG_LENGTH];
	va_list ap;

	va_start(ap, fmt);
	vsnprintf(message, sizeof(message), fmt, ap);
	va_end(ap);

	fprintf(stderr, "%s", message);
}

/*
 * debug_msg - print a debug message to stderr if debug is set
 */
void debug_msg(const char *fmt, ...)
{
	char message[MAX_MSG_LENGTH];
	va_list ap;

	if (!config_debug)
		return;

	va_start(ap, fmt);
	vsnprintf(message, sizeof(message), fmt, ap);
	va_end(ap);

	fprintf(stderr, "%s", message);
}

/*
 * fatal - print an error message and EOL to stderr and exit with ERROR
 */
void fatal(const char *fmt, ...)
{
	va_list ap;

	va_start(ap, fmt);
	vfprintf(stderr, fmt, ap);
	va_end(ap);
	fprintf(stderr, "\n");

	exit(ERROR);
}

/*
 * get_llong_from_str - get a long long int from a string
 */
long long get_llong_from_str(char *start)
{
	long long value;
	char *end;

	errno = 0;
	value = strtoll(start, &end, 10);
	if (errno || start == end)
		return -1;

	return value;
}

/*
 * get_duration - fill output with a human readable duration since start_time
 */
void get_duration(time_t start_time, char *output, int output_size)
{
	time_t now = time(NULL);
	struct tm *tm_info;
	time_t duration;

	duration = difftime(now, start_time);
	tm_info = gmtime(&duration);

	snprintf(output, output_size, "%3d %02d:%02d:%02d",
			tm_info->tm_yday,
			tm_info->tm_hour,
			tm_info->tm_min,
			tm_info->tm_sec);
}

/*
 * parse_cpu_set - parse a cpu_list filling cpu_set_t argument
 *
 * Receives a cpu list, like 1-3,5 (cpus 1, 2, 3, 5), and then set
 * filling cpu_set_t argument.
 *
 * Returns 0 on success, 1 otherwise.
 */
int parse_cpu_set(char *cpu_list, cpu_set_t *set)
{
	const char *p;
	int end_cpu;
	int cpu;
	int i;

	CPU_ZERO(set);

	for (p = cpu_list; *p; ) {
		cpu = atoi(p);
		if (cpu < 0 || (!cpu && *p != '0') || cpu >= nr_cpus)
			goto err;

		while (isdigit(*p))
			p++;
		if (*p == '-') {
			p++;
			end_cpu = atoi(p);
			if (end_cpu < cpu || (!end_cpu && *p != '0') || end_cpu >= nr_cpus)
				goto err;
			while (isdigit(*p))
				p++;
		} else
			end_cpu = cpu;

		if (cpu == end_cpu) {
			debug_msg("cpu_set: adding cpu %d\n", cpu);
			CPU_SET(cpu, set);
		} else {
			for (i = cpu; i <= end_cpu; i++) {
				debug_msg("cpu_set: adding cpu %d\n", i);
				CPU_SET(i, set);
			}
		}

		if (*p == ',')
			p++;
	}

	return 0;
err:
	debug_msg("Error parsing the cpu set %s\n", cpu_list);
	return 1;
}

/*
 * parse_stack_format - parse the stack format
 *
 * Return: the stack format on success, -1 otherwise.
 */
int parse_stack_format(char *arg)
{
	if (!strcmp(arg, "truncate"))
		return STACK_FORMAT_TRUNCATE;
	if (!strcmp(arg, "skip"))
		return STACK_FORMAT_SKIP;
	if (!strcmp(arg, "full"))
		return STACK_FORMAT_FULL;

	debug_msg("Error parsing the stack format %s\n", arg);
	return -1;
}

/*
 * parse_duration - parse duration with s/m/h/d suffix converting it to seconds
 */
long parse_seconds_duration(char *val)
{
	char *end;
	long t;

	t = strtol(val, &end, 10);

	if (end) {
		switch (*end) {
		case 's':
		case 'S':
			break;
		case 'm':
		case 'M':
			t *= 60;
			break;
		case 'h':
		case 'H':
			t *= 60 * 60;
			break;

		case 'd':
		case 'D':
			t *= 24 * 60 * 60;
			break;
		}
	}

	return t;
}

/*
 * match_time_unit - check if str starts with unit followed by end-of-string or ':'
 *
 * This allows the time unit parser to work both in standalone duration strings
 * like "100ms" and in colon-delimited SCHED_DEADLINE specifications like
 * "d:10ms:100ms", while still rejecting malformed input like "100msx".
 */
static bool match_time_unit(const char *str, const char *unit)
{
	size_t len = strlen(unit);

	return strncmp(str, unit, len) == 0 &&
	       (str[len] == '\0' || str[len] == ':');
}

/*
 * parse_ns_duration - parse duration with ns/us/ms/s converting it to nanoseconds
 */
long parse_ns_duration(char *val)
{
	char *end;
	long t;

	t = strtol(val, &end, 10);

	if (end) {
		if (match_time_unit(end, "ns")) {
			return t;
		} else if (match_time_unit(end, "us")) {
			t *= 1000;
			return t;
		} else if (match_time_unit(end, "ms")) {
			t *= 1000 * 1000;
			return t;
		} else if (match_time_unit(end, "s")) {
			t *= 1000 * 1000 * 1000;
			return t;
		}
		return -1;
	}

	return t;
}

/*
 * This is a set of helper functions to use SCHED_DEADLINE.
 */
#ifndef __NR_sched_setattr
# ifdef __x86_64__
#  define __NR_sched_setattr	314
# elif __i386__
#  define __NR_sched_setattr	351
# elif __arm__
#  define __NR_sched_setattr	380
# elif __aarch64__ || __riscv
#  define __NR_sched_setattr	274
# elif __powerpc__
#  define __NR_sched_setattr	355
# elif __s390x__
#  define __NR_sched_setattr	345
# elif __loongarch__
#  define __NR_sched_setattr	274
# endif
#endif

#define SCHED_DEADLINE		6

static inline int syscall_sched_setattr(pid_t pid, const struct sched_attr *attr,
				unsigned int flags) {
	return syscall(__NR_sched_setattr, pid, attr, flags);
}

int __set_sched_attr(int pid, struct sched_attr *attr)
{
	int flags = 0;
	int retval;

	retval = syscall_sched_setattr(pid, attr, flags);
	if (retval < 0) {
		err_msg("Failed to set sched attributes to the pid %d: %s\n",
			pid, strerror(errno));
		return 1;
	}

	return 0;
}

/*
 * procfs_is_workload_pid - check if a procfs entry contains a comm_prefix* comm
 *
 * Check if the procfs entry is a directory of a process, and then check if the
 * process has a comm with the prefix set in char *comm_prefix. As the
 * current users of this function only check for kernel threads, there is no
 * need to check for the threads for the process.
 *
 * Return: True if the proc_entry contains a comm file with comm_prefix*.
 * Otherwise returns false.
 */
static int procfs_is_workload_pid(const char *comm_prefix, struct dirent *proc_entry)
{
	char buffer[MAX_PATH];
	int comm_fd, retval;
	char *t_name;

	if (proc_entry->d_type != DT_DIR)
		return 0;

	if (*proc_entry->d_name == '.')
		return 0;

	/* check if the string is a pid */
	for (t_name = proc_entry->d_name; *t_name; t_name++) {
		if (!isdigit(*t_name))
			break;
	}

	if (*t_name != '\0')
		return 0;

	snprintf(buffer, MAX_PATH, "/proc/%s/comm", proc_entry->d_name);
	comm_fd = open(buffer, O_RDONLY);
	if (comm_fd < 0)
		return 0;

	memset(buffer, 0, MAX_PATH);
	retval = read(comm_fd, buffer, MAX_PATH);

	close(comm_fd);

	if (retval <= 0)
		return 0;

	buffer[MAX_PATH-1] = '\0';
	if (!str_has_prefix(buffer, comm_prefix))
		return 0;

	/* comm already have \n */
	debug_msg("Found workload pid:%s comm:%s", proc_entry->d_name, buffer);

	return 1;
}

/*
 * set_comm_sched_attr - set sched params to threads starting with char *comm_prefix
 *
 * This function uses procfs to list the currently running threads and then set the
 * sched_attr *attr to the threads that start with char *comm_prefix. It is
 * mainly used to set the priority to the kernel threads created by the
 * tracers.
 */
int set_comm_sched_attr(const char *comm_prefix, struct sched_attr *attr)
{
	struct dirent *proc_entry;
	DIR *procfs;
	int retval;
	int pid;

	if (strlen(comm_prefix) >= MAX_PATH) {
		err_msg("Command prefix is too long: %d < strlen(%s)\n",
			MAX_PATH, comm_prefix);
		return 1;
	}

	procfs = opendir("/proc");
	if (!procfs) {
		err_msg("Could not open procfs\n");
		return 1;
	}

	while ((proc_entry = readdir(procfs))) {

		retval = procfs_is_workload_pid(comm_prefix, proc_entry);
		if (!retval)
			continue;

		if (strtoi(proc_entry->d_name, &pid)) {
			err_msg("'%s' is not a valid pid", proc_entry->d_name);
			retval = 1;
			goto out;
		}
		/* procfs_is_workload_pid confirmed it is a pid */
		retval = __set_sched_attr(pid, attr);
		if (retval) {
			err_msg("Error setting sched attributes for pid:%s\n", proc_entry->d_name);
			goto out;
		}

		debug_msg("Set sched attributes for pid:%s\n", proc_entry->d_name);
	}

	retval = 0;
out:
	closedir(procfs);
	return retval;
}

#define INVALID_VAL	(~0L)
static long get_long_ns_after_colon(char *start)
{
	long val = INVALID_VAL;

	/* find the ":" */
	start = strstr(start, ":");
	if (!start)
		return -1;

	/* skip ":" */
	start++;
	val = parse_ns_duration(start);

	return val;
}

static long get_long_after_colon(char *start)
{
	long val = INVALID_VAL;

	/* find the ":" */
	start = strstr(start, ":");
	if (!start)
		return -1;

	/* skip ":" */
	start++;
	val = get_llong_from_str(start);

	return val;
}

/*
 * parse priority in the format:
 * SCHED_OTHER:
 *		o:<prio>
 *		O:<prio>
 * SCHED_RR:
 *		r:<prio>
 *		R:<prio>
 * SCHED_FIFO:
 *		f:<prio>
 *		F:<prio>
 * SCHED_DEADLINE:
 *		d:runtime:period
 *		D:runtime:period
 */
int parse_prio(char *arg, struct sched_attr *sched_param)
{
	long prio;
	long runtime;
	long period;

	memset(sched_param, 0, sizeof(*sched_param));
	sched_param->size = sizeof(*sched_param);

	switch (arg[0]) {
	case 'd':
	case 'D':
		/* d:runtime:period */
		if (strlen(arg) < 4)
			return -1;

		runtime = get_long_ns_after_colon(arg);
		if (runtime == INVALID_VAL)
			return -1;

		period = get_long_ns_after_colon(&arg[2]);
		if (period == INVALID_VAL)
			return -1;

		if (runtime > period)
			return -1;

		sched_param->sched_policy   = SCHED_DEADLINE;
		sched_param->sched_runtime  = runtime;
		sched_param->sched_deadline = period;
		sched_param->sched_period   = period;
		break;
	case 'f':
	case 'F':
		/* f:prio */
		prio = get_long_after_colon(arg);
		if (prio == INVALID_VAL)
			return -1;

		if (prio < sched_get_priority_min(SCHED_FIFO))
			return -1;
		if (prio > sched_get_priority_max(SCHED_FIFO))
			return -1;

		sched_param->sched_policy   = SCHED_FIFO;
		sched_param->sched_priority = prio;
		break;
	case 'r':
	case 'R':
		/* r:prio */
		prio = get_long_after_colon(arg);
		if (prio == INVALID_VAL)
			return -1;

		if (prio < sched_get_priority_min(SCHED_RR))
			return -1;
		if (prio > sched_get_priority_max(SCHED_RR))
			return -1;

		sched_param->sched_policy   = SCHED_RR;
		sched_param->sched_priority = prio;
		break;
	case 'o':
	case 'O':
		/* o:prio */
		prio = get_long_after_colon(arg);
		if (prio == INVALID_VAL)
			return -1;

		if (prio < MIN_NICE)
			return -1;
		if (prio > MAX_NICE)
			return -1;

		sched_param->sched_policy   = SCHED_OTHER;
		sched_param->sched_nice = prio;
		break;
	default:
		return -1;
	}
	return 0;
}

/*
 * set_cpu_dma_latency - set the /dev/cpu_dma_latecy
 *
 * This is used to reduce the exit from idle latency. The value
 * will be reset once the file descriptor of /dev/cpu_dma_latecy
 * is closed.
 *
 * Return: the /dev/cpu_dma_latecy file descriptor
 */
int set_cpu_dma_latency(int32_t latency)
{
	int retval;
	int fd;

	fd = open("/dev/cpu_dma_latency", O_RDWR);
	if (fd < 0) {
		err_msg("Error opening /dev/cpu_dma_latency\n");
		return -1;
	}

	retval = write(fd, &latency, 4);
	if (retval < 1) {
		err_msg("Error setting /dev/cpu_dma_latency\n");
		close(fd);
		return -1;
	}

	debug_msg("Set /dev/cpu_dma_latency to %d\n", latency);

	return fd;
}

#ifdef HAVE_LIBCPUPOWER_SUPPORT
static unsigned int **saved_cpu_idle_disable_state;
static size_t saved_cpu_idle_disable_state_alloc_ctr;

/*
 * save_cpu_idle_state_disable - save disable for all idle states of a cpu
 *
 * Saves the current disable of all idle states of a cpu, to be subsequently
 * restored via restore_cpu_idle_disable_state.
 *
 * Return: idle state count on success, negative on error
 */
int save_cpu_idle_disable_state(unsigned int cpu)
{
	unsigned int nr_states;
	unsigned int state;
	int disabled;

	nr_states = cpuidle_state_count(cpu);

	if (nr_states == 0)
		return 0;

	if (saved_cpu_idle_disable_state == NULL) {
		saved_cpu_idle_disable_state = calloc(nr_cpus, sizeof(unsigned int *));
		if (!saved_cpu_idle_disable_state)
			return -1;
	}

	saved_cpu_idle_disable_state[cpu] = calloc(nr_states, sizeof(unsigned int));
	if (!saved_cpu_idle_disable_state[cpu])
		return -1;
	saved_cpu_idle_disable_state_alloc_ctr++;

	for (state = 0; state < nr_states; state++) {
		disabled = cpuidle_is_state_disabled(cpu, state);
		if (disabled < 0)
			return disabled;
		saved_cpu_idle_disable_state[cpu][state] = disabled;
	}

	return nr_states;
}

/*
 * restore_cpu_idle_disable_state - restore disable for all idle states of a cpu
 *
 * Restores the current disable state of all idle states of a cpu that was
 * previously saved by save_cpu_idle_disable_state.
 *
 * Return: idle state count on success, negative on error
 */
int restore_cpu_idle_disable_state(unsigned int cpu)
{
	unsigned int nr_states;
	unsigned int state;
	int disabled;
	int result;

	nr_states = cpuidle_state_count(cpu);

	if (nr_states == 0)
		return 0;

	if (!saved_cpu_idle_disable_state)
		return -1;

	for (state = 0; state < nr_states; state++) {
		if (!saved_cpu_idle_disable_state[cpu])
			return -1;
		disabled = saved_cpu_idle_disable_state[cpu][state];
		result = cpuidle_state_disable(cpu, state, disabled);
		if (result < 0)
			return result;
	}

	free(saved_cpu_idle_disable_state[cpu]);
	saved_cpu_idle_disable_state[cpu] = NULL;
	saved_cpu_idle_disable_state_alloc_ctr--;
	if (saved_cpu_idle_disable_state_alloc_ctr == 0) {
		free(saved_cpu_idle_disable_state);
		saved_cpu_idle_disable_state = NULL;
	}

	return nr_states;
}

/*
 * free_cpu_idle_disable_states - free saved idle state disable for all cpus
 *
 * Frees the memory used for storing cpu idle state disable for all cpus
 * and states.
 *
 * Normally, the memory is freed automatically in
 * restore_cpu_idle_disable_state; this is mostly for cleaning up after an
 * error.
 */
void free_cpu_idle_disable_states(void)
{
	int cpu;

	if (!saved_cpu_idle_disable_state)
		return;

	for (cpu = 0; cpu < nr_cpus; cpu++) {
		free(saved_cpu_idle_disable_state[cpu]);
		saved_cpu_idle_disable_state[cpu] = NULL;
	}

	free(saved_cpu_idle_disable_state);
	saved_cpu_idle_disable_state = NULL;
}

/*
 * set_deepest_cpu_idle_state - limit idle state of cpu
 *
 * Disables all idle states deeper than the one given in
 * deepest_state (assuming states with higher number are deeper).
 *
 * This is used to reduce the exit from idle latency. Unlike
 * set_cpu_dma_latency, it can disable idle states per cpu.
 *
 * Return: idle state count on success, negative on error
 */
int set_deepest_cpu_idle_state(unsigned int cpu, unsigned int deepest_state)
{
	unsigned int nr_states;
	unsigned int state;
	int result;

	nr_states = cpuidle_state_count(cpu);

	for (state = deepest_state + 1; state < nr_states; state++) {
		result = cpuidle_state_disable(cpu, state, 1);
		if (result < 0)
			return result;
	}

	return nr_states;
}
#endif /* HAVE_LIBCPUPOWER_SUPPORT */

#define _STR(x) #x
#define STR(x) _STR(x)

/*
 * find_mount - find a the mount point of a given fs
 *
 * Returns 0 if mount is not found, otherwise return 1 and fill mp
 * with the mount point.
 */
static const int find_mount(const char *fs, char *mp, int sizeof_mp)
{
	char mount_point[MAX_PATH+1];
	char type[100];
	int found = 0;
	FILE *fp;

	fp = fopen("/proc/mounts", "r");
	if (!fp)
		return 0;

	while (fscanf(fp, "%*s %" STR(MAX_PATH) "s %99s %*s %*d %*d\n",	mount_point, type) == 2) {
		if (strcmp(type, fs) == 0) {
			found = 1;
			break;
		}
	}
	fclose(fp);

	if (!found)
		return 0;

	memset(mp, 0, sizeof_mp);
	strncpy(mp, mount_point, sizeof_mp - 1);

	debug_msg("Fs %s found at %s\n", fs, mp);
	return 1;
}

/*
 * get_self_cgroup - get the current thread cgroup path
 *
 * Parse /proc/$$/cgroup file to get the thread's cgroup. As an example of line to parse:
 *
 * 0::/user.slice/user-0.slice/session-3.scope'\n'
 *
 * This function is interested in the content after the second : and before the '\n'.
 *
 * Returns 1 if a string was found, 0 otherwise.
 */
static int get_self_cgroup(char *self_cg, int sizeof_self_cg)
{
	char path[MAX_PATH], *start;
	int fd, retval;

	snprintf(path, MAX_PATH, "/proc/%d/cgroup", getpid());

	fd = open(path, O_RDONLY);
	if (fd < 0)
		return 0;

	memset(path, 0, sizeof(path));
	retval = read(fd, path, MAX_PATH);

	close(fd);

	if (retval <= 0)
		return 0;

	path[MAX_PATH-1] = '\0';
	start = path;

	start = strstr(start, ":");
	if (!start)
		return 0;

	/* skip ":" */
	start++;

	start = strstr(start, ":");
	if (!start)
		return 0;

	/* skip ":" */
	start++;

	if (strlen(start) >= sizeof_self_cg)
		return 0;

	snprintf(self_cg, sizeof_self_cg, "%s", start);

	/* Swap '\n' with '\0' */
	start = strstr(self_cg, "\n");

	/* there must be '\n' */
	if (!start)
		return 0;

	/* ok, it found a string after the second : and before the \n */
	*start = '\0';

	return 1;
}

/*
 * open_cgroup_procs - Open the cgroup.procs file for the given cgroup
 *
 * If cgroup argument is not NULL, the cgroup.procs file for that cgroup
 * will be opened. Otherwise, the cgroup of the calling, i.e., rtla, thread
 * will be used.
 *
 * Supports cgroup v2.
 *
 * Returns the file descriptor on success, -1 otherwise.
 */
static int open_cgroup_procs(const char *cgroup)
{
	char cgroup_path[MAX_PATH - strlen("/cgroup.procs")];
	char cgroup_procs[MAX_PATH];
	int retval;
	int cg_fd;
	size_t cg_path_len;

	retval = find_mount("cgroup2", cgroup_path, sizeof(cgroup_path));
	if (!retval) {
		err_msg("Did not find cgroupv2 mount point\n");
		return -1;
	}

	cg_path_len = strlen(cgroup_path);

	if (!cgroup) {
		retval = get_self_cgroup(&cgroup_path[cg_path_len],
				sizeof(cgroup_path) - cg_path_len);
		if (!retval) {
			err_msg("Did not find self cgroup\n");
			return -1;
		}
	} else {
		snprintf(&cgroup_path[cg_path_len],
				sizeof(cgroup_path) - cg_path_len, "%s/", cgroup);
	}

	snprintf(cgroup_procs, MAX_PATH, "%s/cgroup.procs", cgroup_path);

	debug_msg("Using cgroup path at: %s\n", cgroup_procs);

	cg_fd = open(cgroup_procs, O_RDWR);
	if (cg_fd < 0)
		return -1;

	return cg_fd;
}

/*
 * set_pid_cgroup - Set cgroup to pid_t pid
 *
 * If cgroup argument is not NULL, the threads will move to the given cgroup.
 * Otherwise, the cgroup of the calling, i.e., rtla, thread will be used.
 *
 * Supports cgroup v2.
 *
 * Returns 1 on success, 0 otherwise.
 */
int set_pid_cgroup(pid_t pid, const char *cgroup)
{
	char pid_str[24];
	int retval;
	int cg_fd;

	cg_fd = open_cgroup_procs(cgroup);
	if (cg_fd < 0)
		return 0;

	snprintf(pid_str, sizeof(pid_str), "%d\n", pid);

	retval = write(cg_fd, pid_str, strlen(pid_str));
	if (retval < 0)
		err_msg("Error setting cgroup attributes for pid:%s - %s\n",
				pid_str, strerror(errno));
	else
		debug_msg("Set cgroup attributes for pid:%s\n", pid_str);

	close(cg_fd);

	return (retval >= 0);
}

/**
 * set_comm_cgroup - Set cgroup to threads starting with char *comm_prefix
 *
 * If cgroup argument is not NULL, the threads will move to the given cgroup.
 * Otherwise, the cgroup of the calling, i.e., rtla, thread will be used.
 *
 * Supports cgroup v2.
 *
 * Returns 1 on success, 0 otherwise.
 */
int set_comm_cgroup(const char *comm_prefix, const char *cgroup)
{
	struct dirent *proc_entry;
	DIR *procfs;
	int retval;
	int cg_fd;

	if (strlen(comm_prefix) >= MAX_PATH) {
		err_msg("Command prefix is too long: %d < strlen(%s)\n",
			MAX_PATH, comm_prefix);
		return 0;
	}

	cg_fd = open_cgroup_procs(cgroup);
	if (cg_fd < 0)
		return 0;

	procfs = opendir("/proc");
	if (!procfs) {
		err_msg("Could not open procfs\n");
		goto out_cg;
	}

	while ((proc_entry = readdir(procfs))) {

		retval = procfs_is_workload_pid(comm_prefix, proc_entry);
		if (!retval)
			continue;

		retval = write(cg_fd, proc_entry->d_name, strlen(proc_entry->d_name));
		if (retval < 0) {
			err_msg("Error setting cgroup attributes for pid:%s - %s\n",
				proc_entry->d_name, strerror(errno));
			goto out_procfs;
		}

		debug_msg("Set cgroup attributes for pid:%s\n", proc_entry->d_name);
	}

	closedir(procfs);
	close(cg_fd);
	return 1;

out_procfs:
	closedir(procfs);
out_cg:
	close(cg_fd);
	return 0;
}

/**
 * auto_house_keeping - Automatically move rtla out of measurement threads
 *
 * Try to move rtla away from the tracer, if possible.
 *
 * Returns 1 on success, 0 otherwise.
 */
int auto_house_keeping(cpu_set_t *monitored_cpus)
{
	cpu_set_t rtla_cpus, house_keeping_cpus;
	int retval;

	/* first get the CPUs in which rtla can actually run. */
	retval = sched_getaffinity(getpid(), sizeof(rtla_cpus), &rtla_cpus);
	if (retval == -1) {
		debug_msg("Could not get rtla affinity, rtla might run with the threads!\n");
		return 0;
	}

	/* then check if the existing setup is already good. */
	CPU_AND(&house_keeping_cpus, &rtla_cpus, monitored_cpus);
	if (!CPU_COUNT(&house_keeping_cpus)) {
		debug_msg("rtla and the monitored CPUs do not share CPUs.");
		debug_msg("Skipping auto house-keeping\n");
		return 1;
	}

	/* remove the intersection */
	CPU_XOR(&house_keeping_cpus, &rtla_cpus, monitored_cpus);

	/* get only those that rtla can run */
	CPU_AND(&house_keeping_cpus, &house_keeping_cpus, &rtla_cpus);

	/* is there any cpu left? */
	if (!CPU_COUNT(&house_keeping_cpus)) {
		debug_msg("Could not find any CPU for auto house-keeping\n");
		return 0;
	}

	retval = sched_setaffinity(getpid(), sizeof(house_keeping_cpus), &house_keeping_cpus);
	if (retval == -1) {
		debug_msg("Could not set affinity for auto house-keeping\n");
		return 0;
	}

	debug_msg("rtla automatically moved to an auto house-keeping cpu set\n");

	return 1;
}

/*
 * strtoi - convert string to integer with error checking
 *
 * Returns 0 on success, -1 if conversion fails or result is out of int range.
 */
int strtoi(const char *s, int *res)
{
	char *end_ptr;
	long lres;

	if (!*s)
		return -1;

	errno = 0;
	lres = strtol(s, &end_ptr, 0);
	if (errno || *end_ptr || lres > INT_MAX || lres < INT_MIN)
		return -1;

	*res = (int) lres;
	return 0;
}

static inline void fatal_alloc(void)
{
	fatal("Error allocating memory\n");
}

void *calloc_fatal(size_t n, size_t size)
{
	void *p = calloc(n, size);

	if (!p)
		fatal_alloc();

	return p;
}

void *reallocarray_fatal(void *p, size_t n, size_t size)
{
	p = reallocarray(p, n, size);

	if (!p)
		fatal_alloc();

	return p;
}

char *strdup_fatal(const char *s)
{
	char *p = strdup(s);

	if (!p)
		fatal_alloc();

	return p;
}
