// 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 "utils.h"

#define MAX_MSG_LENGTH	1024
int 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 nr_cpus;
	int cpu;
	int i;

	CPU_ZERO(set);

	nr_cpus = sysconf(_SC_NPROCESSORS_CONF);

	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_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;
}

/*
 * 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 (!strncmp(end, "ns", 2)) {
			return t;
		} else if (!strncmp(end, "us", 2)) {
			t *= 1000;
			return t;
		} else if (!strncmp(end, "ms", 2)) {
			t *= 1000 * 1000;
			return t;
		} else if (!strncmp(end, "s", 1)) {
			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';
	retval = strncmp(comm_prefix, buffer, strlen(comm_prefix));
	if (retval)
		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);
			goto out_err;
		}
		/* 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_err;
		}

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

out_err:
	closedir(procfs);
	return 1;
}

#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;
	int nr_cpus;

	nr_states = cpuidle_state_count(cpu);

	if (nr_states == 0)
		return 0;

	if (saved_cpu_idle_disable_state == NULL) {
		nr_cpus = sysconf(_SC_NPROCESSORS_CONF);
		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;
	int nr_cpus;

	if (!saved_cpu_idle_disable_state)
		return;

	nr_cpus = sysconf(_SC_NPROCESSORS_CONF);

	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;

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

	if (!cgroup) {
		retval = get_self_cgroup(&cgroup_path[strlen(cgroup_path)],
				sizeof(cgroup_path) - strlen(cgroup_path));
		if (!retval) {
			err_msg("Did not find self cgroup\n");
			return -1;
		}
	} else {
		snprintf(&cgroup_path[strlen(cgroup_path)],
				sizeof(cgroup_path) - strlen(cgroup_path), "%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;
}

/**
 * parse_optional_arg - Parse optional argument value
 *
 * Parse optional argument value, which can be in the form of:
 * -sarg, -s/--long=arg, -s/--long arg
 *
 * Returns arg value if found, NULL otherwise.
 */
char *parse_optional_arg(int argc, char **argv)
{
	if (optarg) {
		if (optarg[0] == '=') {
			/* skip the = */
			return &optarg[1];
		} else {
			return optarg;
		}
	/* parse argument of form -s [arg] and --long [arg]*/
	} else if (optind < argc && argv[optind][0] != '-') {
		/* consume optind */
		return argv[optind++];
	} else {
		return NULL;
	}
}

/*
 * 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;
}
