/* Copyright (c) 2015 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details. */

#include <parlib/parlib.h>
#include <parlib/core_set.h>
#include <parlib/ros_debug.h>
#include <parlib/event.h>
#include <stdlib.h>

/* Control variables */
bool parlib_wants_to_be_mcp = TRUE;
bool parlib_never_yield = FALSE;
bool parlib_never_vc_request = FALSE;

/* Creates a child process for program @exe, with args and envs.  Will attempt
 * to look in /bin/ if the initial lookup fails, and will invoke sh to handle
 * non-elfs.  Returns the child's PID on success, -1 o/w. */
pid_t create_child(const char *exe, int argc, char *const argv[],
                   char *const envp[])
{
	pid_t kid;
	char *path_exe;
	char **sh_argv;
	const char *sh_path = "/bin/sh";

	kid = sys_proc_create(exe, strlen(exe), argv, envp, 0);
	if (kid > 0)
		return kid;

	/* Here's how we avoid infinite recursion.  We can only have ENOENT the
	 * first time through without bailing out, since all errno paths set exe
	 * to begin with '/'.  That includes calls from ENOEXEC, since sh_path
	 * begins with /.  To avoid repeated calls to ENOEXEC, we just look for
	 * sh_path as the exe, so if we have consecutive ENOEXECs, we'll bail
	 * out. */
	switch (errno) {
	case ENOENT:
		if (exe[0] == '/')
			return -1;
		path_exe = malloc(MAX_PATH_LEN);
		if (!path_exe)
			return -1;
		/* Our 'PATH' is only /bin. */
		snprintf(path_exe, MAX_PATH_LEN, "/bin/%s", exe);
		path_exe[MAX_PATH_LEN - 1] = 0;
		kid = create_child(path_exe, argc, argv, envp);
		free(path_exe);
		break;
	case ENOEXEC:
		/* In case someone replaces /bin/sh with a non-elf. */
		if (!strcmp(sh_path, exe))
			return -1;
		/* We want enough space for the original argv, plus one entry at
		 * the front for sh_path.  When we grab the original argv, we
		 * also need the trailing NULL, which is at argv[argc].  That
		 * means we really want argc + 1 entries from argv. */
		sh_argv = malloc(sizeof(char *) * (argc + 2));
		if (!sh_argv)
			return -1;
		memcpy(&sh_argv[1], argv, sizeof(char *) * (argc + 1));
		sh_argv[0] = (char*)sh_path;
		/* Replace the original argv[0] with the path to exe, which
		 * might have been edited to include /bin/ */
		sh_argv[1] = (char*)exe;
		kid = create_child(sh_path, argc + 1, sh_argv, envp);
		free(sh_argv);
		break;
	default:
		return -1;
	}
	return kid;
}

/* Creates a child process for exe, and shares the parent's standard FDs (stdin,
 * stdout, stderr) with the child.  Returns the child's PID on success, -1 o/w.
 */
pid_t create_child_with_stdfds(const char *exe, int argc, char *const argv[],
                               char *const envp[])
{
	struct childfdmap fd_dups[3] = { {0, 0}, {1, 1}, {2, 2} };
	pid_t kid;
	int ret;

	kid = create_child(exe, argc, argv, envp);
	if (kid < 0)
		return -1;
	ret = syscall(SYS_dup_fds_to, kid, fd_dups, COUNT_OF(fd_dups));
	if (ret != COUNT_OF(fd_dups)) {
		sys_proc_destroy(kid, -1);
		return -1;
	}
	return kid;
}

/* Provisions the CG cores to PID.  Returns -1 if any of them fail. */
int provision_core_set(pid_t pid, const struct core_set *cores)
{
	struct core_set pvcores;
	size_t max_cores = parlib_nr_total_cores();

	parlib_get_ll_core_set(&pvcores);
	parlib_not_core_set(&pvcores);
	parlib_and_core_sets(&pvcores, cores);
	for (size_t i = 0; i < max_cores; i++) {
		if (parlib_get_core(&pvcores, i)) {
			if (sys_provision(pid, RES_CORES, i))
				return -1;
		}
	}
	return 0;
}

/* This sets up 'handler' to be run when the process receives EV_FREE_APPLE_PIE
 * (9).  You can send this event with the notify utility:
 *
 *	notify PID 9 [Arg1 Arg2 0xArg3 Arg4]
 *
 * A simple debug handler can switch on an arg:

	static void notify_ipi(struct event_msg *ev_msg, unsigned int ev_type,
	                       void *data)
	{
		switch (ev_msg->ev_arg1) {
		case 1:
			// do something
			break;
		case 2:
			// do something else
			break;
		default:
			printf("Unknown arg %d\n", ev_msg->ev_arg1);
			break;
		}
	}

 */
void set_notify_9(void (*handler)(struct event_msg *ev_msg,
				  unsigned int ev_type, void *data),
		  void *data)
{
	struct event_queue *evq;

	register_ev_handler(EV_FREE_APPLE_PIE, handler, data);
	evq = get_eventq(EV_MBOX_UCQ);
	evq->ev_flags = EVENT_IPI | EVENT_INDIR | EVENT_SPAM_INDIR |
		        EVENT_WAKEUP;
	register_kevent_q(evq, EV_FREE_APPLE_PIE);
}
