/* Copyright (c) 2009, 2012, 2015 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Valmon Leymarie <leymariv@berkeley.edu>
 * Kevin Klues <klueska@cs.berkeley.edu>
 * See LICENSE for details.
 */

#include <env.h>
#include <schedule.h>

/* Provision a core to proc p. This code assumes that the scheduler that uses
 * it holds a lock for the duration of the call. */
void __provision_core(struct proc *p, uint32_t pcoreid)
{
	struct sched_pcore *spc = pcoreid2spc(pcoreid);
	struct sched_pcore_tailq *prov_list;

	/* If the core is already prov to someone else, take it away.  (last write
	 * wins, some other layer or new func can handle permissions). */
	if (spc->prov_proc) {
		/* the list the spc is on depends on whether it is alloced to the
		 * prov_proc or not */
		prov_list = (spc->alloc_proc == spc->prov_proc ?
		             &spc->prov_proc->ksched_data.crd.prov_alloc_me :
		             &spc->prov_proc->ksched_data.crd.prov_not_alloc_me);
		TAILQ_REMOVE(prov_list, spc, prov_next);
	}
	/* Now prov it to p.  Again, the list it goes on depends on whether it is
	 * alloced to p or not.  Callers can also send in 0 to de-provision. */
	if (p) {
		if (spc->alloc_proc == p) {
			TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_alloc_me, spc,
			                  prov_next);
		} else {
			/* this is be the victim list, which can be sorted so that we pick
			 * the right victim (sort by alloc_proc reverse priority, etc). */
			TAILQ_INSERT_TAIL(&p->ksched_data.crd.prov_not_alloc_me, spc,
			                  prov_next);
		}
	}
	spc->prov_proc = p;
}

/* Unprovisions any pcores for the given list */
static void __unprov_pcore_list(struct sched_pcore_tailq *list_head)
{
	struct sched_pcore *spc_i;
	/* We can leave them connected within the tailq, since the scps don't have a
	 * default list (if they aren't on a proc's list, then we don't care about
	 * them), and since the INSERTs don't care what list you were on before
	 * (chummy with the implementation).  Pretty sure this is right.  If there's
	 * suspected list corruption, be safer here. */
	TAILQ_FOREACH(spc_i, list_head, prov_next)
		spc_i->prov_proc = 0;
	TAILQ_INIT(list_head);
}

/* Unprovision all cores from proc p. This code assumes that the scheduler
 * that uses * it holds a lock for the duration of the call. */
void __unprovision_all_cores(struct proc *p)
{
	__unprov_pcore_list(&p->ksched_data.crd.prov_alloc_me);
	__unprov_pcore_list(&p->ksched_data.crd.prov_not_alloc_me);
}

/* Print a list of the cores currently provisioned to p. */
void print_proc_coreprov(struct proc *p)
{
	struct sched_pcore *spc_i;

	if (!p)
		return;
	print_lock();
	printk("Prov cores alloced to proc %d (%p)\n----------\n", p->pid, p);
	TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_alloc_me, prov_next)
		printk("Pcore %d\n", spc2pcoreid(spc_i));
	printk("Prov cores not alloced to proc %d (%p)\n----------\n", p->pid, p);
	TAILQ_FOREACH(spc_i, &p->ksched_data.crd.prov_not_alloc_me, prov_next)
		printk("Pcore %d (alloced to %d (%p))\n", spc2pcoreid(spc_i),
		       spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
		       spc_i->alloc_proc);
	print_unlock();
}

/* Print the processes attached to each provisioned core. */
void print_coreprov_map(void)
{
	struct sched_pcore *spc_i;

	/* Doing this without a scheduler lock, which is dangerous, but won't
	 * deadlock */
	print_lock();
	printk("Which cores are provisioned to which procs:\n------------------\n");
	for (int i = 0; i < num_cores; i++) {
		spc_i = pcoreid2spc(i);
		printk("Core %02d, prov: %d(%p) alloc: %d(%p)\n", i,
		       spc_i->prov_proc ? spc_i->prov_proc->pid : 0, spc_i->prov_proc,
		       spc_i->alloc_proc ? spc_i->alloc_proc->pid : 0,
		       spc_i->alloc_proc);
	}
	print_unlock();
}
