/* Copyright (c) 2010-13 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Kernel threading.  These are for blocking within the kernel for whatever
 * reason, usually during blocking IO operations. */

#include <kthread.h>
#include <slab.h>
#include <page_alloc.h>
#include <pmap.h>
#include <smp.h>
#include <schedule.h>
#include <kstack.h>
#include <arch/uaccess.h>

uintptr_t get_kstack(void)
{
	uintptr_t stackbot;
	if (KSTKSIZE == PGSIZE)
		stackbot = (uintptr_t)kpage_alloc_addr();
	else
		stackbot = (uintptr_t)get_cont_pages(KSTKSHIFT - PGSHIFT, 0);
	assert(stackbot);
	return stackbot + KSTKSIZE;
}

void put_kstack(uintptr_t stacktop)
{
	uintptr_t stackbot = stacktop - KSTKSIZE;
	if (KSTKSIZE == PGSIZE)
		page_decref(kva2page((void*)stackbot));
	else
		free_cont_pages((void*)stackbot, KSTKSHIFT - PGSHIFT);
}

uintptr_t *kstack_bottom_addr(uintptr_t stacktop)
{
	/* canary at the bottom of the stack */
	assert(!PGOFF(stacktop));
	return (uintptr_t*)(stacktop - KSTKSIZE);
}

struct kmem_cache *kthread_kcache;

void kthread_init(void)
{
	kthread_kcache = kmem_cache_create("kthread", sizeof(struct kthread),
	                                   __alignof__(struct kthread), 0, 0, 0);
}

/* Used by early init routines (smp_boot, etc) */
struct kthread *__kthread_zalloc(void)
{
	struct kthread *kthread;
	kthread = kmem_cache_alloc(kthread_kcache, 0);
	assert(kthread);
	memset(kthread, 0, sizeof(struct kthread));
	return kthread;
}

/* Starts kthread on the calling core.  This does not return, and will handle
 * the details of cleaning up whatever is currently running (freeing its stack,
 * etc).  Pairs with sem_down(). */
void restart_kthread(struct kthread *kthread)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	uintptr_t current_stacktop;
	struct kthread *current_kthread;
	/* Avoid messy complications.  The kthread will enable_irqsave() when it
	 * comes back up. */
	disable_irq();
	/* Free any spare, since we need the current to become the spare.  Without
	 * the spare, we can't free our current kthread/stack (we could free the
	 * kthread, but not the stack, since we're still on it).  And we can't free
	 * anything after popping kthread, since we never return. */
	if (pcpui->spare) {
		put_kstack(pcpui->spare->stacktop);
		kmem_cache_free(kthread_kcache, pcpui->spare);
	}
	current_kthread = pcpui->cur_kthread;
	current_stacktop = current_kthread->stacktop;
	assert(!current_kthread->sysc);	/* catch bugs, prev user should clear */
	/* Set the spare stuff (current kthread, which includes its stacktop) */
	pcpui->spare = current_kthread;
	/* When a kthread runs, its stack is the default kernel stack */
	set_stack_top(kthread->stacktop);
	pcpui->cur_kthread = kthread;
#ifdef CONFIG_KTHREAD_POISON
	/* Assert and switch to cur stack not in use, kthr stack in use */
	uintptr_t *cur_stack_poison, *kth_stack_poison;
	cur_stack_poison = kstack_bottom_addr(current_stacktop);
	assert(*cur_stack_poison == 0xdeadbeef);
	*cur_stack_poison = 0;
	kth_stack_poison = kstack_bottom_addr(kthread->stacktop);
	assert(!*kth_stack_poison);
	*kth_stack_poison = 0xdeadbeef;
#endif /* CONFIG_KTHREAD_POISON */
	/* Only change current if we need to (the kthread was in process context) */
	if (kthread->proc) {
		/* Load our page tables before potentially decreffing cur_proc */
		lcr3(kthread->proc->env_cr3);
		/* Might have to clear out an existing current.  If they need to be set
		 * later (like in restartcore), it'll be done on demand. */
		if (pcpui->cur_proc)
			proc_decref(pcpui->cur_proc);
		/* We also transfer our counted ref from kthread->proc to cur_proc */
		pcpui->cur_proc = kthread->proc;
	}
	/* Finally, restart our thread */
	longjmp(&kthread->context, 1);
}

/* Kmsg handler to launch/run a kthread.  This must be a routine message, since
 * it does not return.  */
static void __launch_kthread(uint32_t srcid, long a0, long a1, long a2)
{
	struct kthread *kthread = (struct kthread*)a0;
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct proc *cur_proc = pcpui->cur_proc;

	/* Make sure we are a routine kmsg */
	assert(in_early_rkmsg_ctx(pcpui));
	if (pcpui->owning_proc && pcpui->owning_proc != kthread->proc) {
		/* Some process should be running here that is not the same as the
		 * kthread.  This means the _M is getting interrupted or otherwise
		 * delayed.  If we want to do something other than run it (like send the
		 * kmsg to another pcore, or ship the context from here to somewhere
		 * else/deschedule it (like for an _S)), do it here.
		 *
		 * If you want to do something here, call out to the ksched, then
		 * abandon_core(). */
		cmb();	/* do nothing/placeholder */
	}
	/* o/w, just run the kthread.  any trapframes that are supposed to run or
	 * were interrupted will run whenever the kthread smp_idles() or otherwise
	 * finishes.  We also need to clear the RKMSG context since we will not
	 * return from restart_kth. */
	clear_rkmsg(pcpui);
	restart_kthread(kthread);
	assert(0);
}

/* Call this when a kthread becomes runnable/unblocked.  We don't do anything
 * particularly smart yet, but when we do, we can put it here. */
void kthread_runnable(struct kthread *kthread)
{
	uint32_t dst = core_id();
	#if 0
	/* turn this block on if you want to test migrating non-core0 kthreads */
	switch (dst) {
		case 0:
			break;
		case 7:
			dst = 2;
			break;
		default:
			dst++;
	}
	#endif
	/* For lack of anything better, send it to ourselves. (TODO: KSCHED) */
	send_kernel_message(dst, __launch_kthread, (long)kthread, 0, 0,
	                    KMSG_ROUTINE);
}

/* Kmsg helper for kthread_yield */
static void __wake_me_up(uint32_t srcid, long a0, long a1, long a2)
{
	struct semaphore *sem = (struct semaphore*)a0;
	assert(sem_up(sem));
}

/* Stop the current kthread.  It'll get woken up next time we run routine kmsgs,
 * after all existing kmsgs are processed. */
void kthread_yield(void)
{
	struct semaphore local_sem, *sem = &local_sem;
	sem_init(sem, 0);
	send_kernel_message(core_id(), __wake_me_up, (long)sem, 0, 0,
	                    KMSG_ROUTINE);
	sem_down(sem);
}

void kthread_usleep(uint64_t usec)
{
	ERRSTACK(1);
	/* TODO: classic ksched issue: where do we want the wake up to happen? */
	struct timer_chain *tchain = &per_cpu_info[core_id()].tchain;
	struct rendez rv;

	int ret_zero(void *ignored)
	{
		return 0;
	}

	/* "discard the error" style (we run the conditional code) */
	if (!waserror()) {
		rendez_init(&rv);
		rendez_sleep_timeout(&rv, ret_zero, 0, usec);
	}
	poperror();
}

static void __ktask_wrapper(uint32_t srcid, long a0, long a1, long a2)
{
	ERRSTACK(1);
	void (*fn)(void*) = (void (*)(void*))a0;
	void *arg = (void*)a1;
	char *name = (char*)a2;
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	assert(is_ktask(pcpui->cur_kthread));
	pcpui->cur_kthread->name = name;
	/* There are some rendezs out there that aren't wrapped.  Though no one can
	 * abort them.  Yet. */
	if (waserror()) {
		printk("Ktask %s threw error %s\n", name, current_errstr());
		goto out;
	}
	enable_irq();
	fn(arg);
out:
	disable_irq();
	pcpui->cur_kthread->name = 0;
	poperror();
	/* if we blocked, when we return, PRKM will smp_idle() */
}

/* Creates a kernel task, running fn(arg), named "name".  This is just a routine
 * kernel message that happens to have a name, and is allowed to block.  It
 * won't be associated with any process.  For lack of a better place, we'll just
 * start it on the calling core.  Caller (and/or fn) need to deal with the
 * storage for *name. */
void ktask(char *name, void (*fn)(void*), void *arg)
{
	send_kernel_message(core_id(), __ktask_wrapper, (long)fn, (long)arg,
	                    (long)name, KMSG_ROUTINE);
}

void check_poison(char *msg)
{
#ifdef CONFIG_KTHREAD_POISON
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	if (pcpui->cur_kthread && pcpui->cur_kthread->stacktop &&
	    (*kstack_bottom_addr(pcpui->cur_kthread->stacktop) != 0xdeadbeef)) {
		printk("\nBad kthread canary, msg: %s\n", msg);
		panic("");
	}
#endif /* CONFIG_KTHREAD_POISON */
}

/* Semaphores, using kthreads directly */
static void debug_downed_sem(struct semaphore *sem);
static void debug_upped_sem(struct semaphore *sem);
static void debug_lock_semlist(void);
static void debug_unlock_semlist(void);

static void sem_init_common(struct semaphore *sem, int signals)
{
	TAILQ_INIT(&sem->waiters);
	sem->nr_signals = signals;
#ifdef CONFIG_SEMAPHORE_DEBUG
	sem->is_on_list = FALSE;
	sem->bt_pc = 0;
	sem->bt_fp = 0;
	sem->calling_core = 0;
#endif
}

void sem_init(struct semaphore *sem, int signals)
{
	sem_init_common(sem, signals);
	spinlock_init(&sem->lock);
	sem->irq_okay = FALSE;
}

void sem_init_irqsave(struct semaphore *sem, int signals)
{
	sem_init_common(sem, signals);
	spinlock_init_irqsave(&sem->lock);
	sem->irq_okay = TRUE;
}

bool sem_trydown(struct semaphore *sem)
{
	bool ret = FALSE;
	/* lockless peek */
	if (sem->nr_signals <= 0)
		return ret;
	debug_lock_semlist();
	spin_lock(&sem->lock);
	if (sem->nr_signals > 0) {
		sem->nr_signals--;
		ret = TRUE;
		debug_downed_sem(sem);
	}
	spin_unlock(&sem->lock);
	debug_unlock_semlist();
	return ret;
}

/* This downs the semaphore and suspends the current kernel context on its
 * waitqueue if there are no pending signals.  Note that the case where the
 * signal is already there is not optimized. */
void sem_down(struct semaphore *sem)
{
	struct kthread *kthread, *new_kthread;
	register uintptr_t new_stacktop;
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	bool irqs_were_on = irq_is_enabled();

	assert(can_block(pcpui));
	/* Make sure we aren't holding any locks (only works if SPINLOCK_DEBUG) */
	if (pcpui->lock_depth)
		panic("Kthread tried to sleep, with lockdepth %d\n", pcpui->lock_depth);
	assert(pcpui->cur_kthread);
	/* Try to down the semaphore.  If there is a signal there, we can skip all
	 * of the sleep prep and just return. */
#ifdef CONFIG_SEM_SPINWAIT
	for (int i = 0; i < CONFIG_SEM_SPINWAIT_NR_LOOPS; i++) {
		if (sem_trydown(sem))
			goto block_return_path;
		cpu_relax();
	}
#else
	if (sem_trydown(sem))
		goto block_return_path;
#endif
#ifdef CONFIG_SEM_TRACE_BLOCKERS
	TRACEME();
#endif
	/* We're probably going to sleep, so get ready.  We'll check again later. */
	kthread = pcpui->cur_kthread;
	/* We need to have a spare slot for restart, so we also use it when
	 * sleeping.  Right now, we need a new kthread to take over if/when our
	 * current kthread sleeps.  Use the spare, and if not, get a new one.
	 *
	 * Note we do this with interrupts disabled (which protects us from
	 * concurrent modifications). */
	if (pcpui->spare) {
		new_kthread = pcpui->spare;
		new_stacktop = new_kthread->stacktop;
		pcpui->spare = 0;
		/* The old flags could have KTH_IS_KTASK set.  The reason is that the
		 * launching of blocked kthreads also uses PRKM, and that KMSG
		 * (__launch_kthread) doesn't return.  Thus the soon-to-be spare
		 * kthread, that is launching another, has flags & KTH_IS_KTASK set. */
		new_kthread->flags = KTH_DEFAULT_FLAGS;
		new_kthread->proc = 0;
		new_kthread->name = 0;
	} else {
		new_kthread = __kthread_zalloc();
		new_kthread->flags = KTH_DEFAULT_FLAGS;
		new_stacktop = get_kstack();
		new_kthread->stacktop = new_stacktop;
#ifdef CONFIG_KTHREAD_POISON
		*kstack_bottom_addr(new_stacktop) = 0;
#endif /* CONFIG_KTHREAD_POISON */
	}
	/* Set the core's new default stack and kthread */
	set_stack_top(new_stacktop);
	pcpui->cur_kthread = new_kthread;
#ifdef CONFIG_KTHREAD_POISON
	/* Mark the new stack as in-use, and unmark the current kthread */
	uintptr_t *new_stack_poison, *kth_stack_poison;
	new_stack_poison = kstack_bottom_addr(new_stacktop);
	assert(!*new_stack_poison);
	*new_stack_poison = 0xdeadbeef;
	kth_stack_poison = kstack_bottom_addr(kthread->stacktop);
	assert(*kth_stack_poison == 0xdeadbeef);
	*kth_stack_poison = 0;
#endif /* CONFIG_KTHREAD_POISON */
	/* Kthreads that are ktasks are not related to any process, and do not need
	 * to work in a process's address space.  They can operate in any address
	 * space that has the kernel mapped (like boot_pgdir, or any pgdir).  Some
	 * ktasks may switch_to, at which point they do care about the address
	 * space and must maintain a reference.
	 *
	 * Normal kthreads need to stay in the process context, but we want the core
	 * (which could be a vcore) to stay in the context too. */
	if (kthread->flags & KTH_SAVE_ADDR_SPACE) {
		kthread->proc = current;
		assert(kthread->proc);
		/* In the future, we could check owning_proc. If it isn't set, we could
		 * clear current and transfer the refcnt to kthread->proc. */
		proc_incref(kthread->proc, 1);
	} else {
		kthread->proc = 0;
	}
	if (setjmp(&kthread->context))
		goto block_return_path;
	debug_lock_semlist();
	spin_lock(&sem->lock);
	if (sem->nr_signals-- <= 0) {
		TAILQ_INSERT_TAIL(&sem->waiters, kthread, link);
		debug_downed_sem(sem);	/* need to debug after inserting */
		/* At this point, we know we'll sleep and change stacks later.  Once we
		 * unlock, we could have the kthread restarted (possibly on another
		 * core), so we need to disable irqs until we are on our new stack.
		 * Otherwise, if we take an IRQ, we'll be using our stack while another
		 * core is using it (restarted kthread).  Basically, disabling irqs
		 * allows us to atomically unlock and 'yield'.  Also, IRQs might have
		 * already been disabled if this was an irqsave sem. */
		disable_irq();
		spin_unlock(&sem->lock);
		debug_unlock_semlist();
		/* Switch to the core's default stack.  After this, don't use local
		 * variables. */
		set_stack_pointer(new_stacktop);
		smp_idle();							/* reenables irqs eventually */
		assert(0);
	}
	/* We get here if we should not sleep on sem (the signal beat the sleep).
	 * We debug_downed_sem since we actually downed it - just didn't sleep. */
	debug_downed_sem(sem);
	spin_unlock(&sem->lock);
	debug_unlock_semlist();
	printd("[kernel] Didn't sleep, unwinding...\n");
	/* Restore the core's current and default stacktop */
	current = kthread->proc;			/* arguably unnecessary */
	if (kthread->proc)
		proc_decref(kthread->proc);
	set_stack_top(kthread->stacktop);
	pcpui->cur_kthread = kthread;
	/* Save the allocs as the spare */
	assert(!pcpui->spare);
	pcpui->spare = new_kthread;
#ifdef CONFIG_KTHREAD_POISON
	/* switch back to old stack in use, new one not */
	*new_stack_poison = 0;
	*kth_stack_poison = 0xdeadbeef;
#endif /* CONFIG_KTHREAD_POISON */
block_return_path:
	printd("[kernel] Returning from being 'blocked'! at %llu\n", read_tsc());
	/* restart_kthread and longjmp did not reenable IRQs.  We need to make sure
	 * irqs are on if they were on when we started to block.  If they were
	 * already on and we short-circuited the block, it's harmless to reenable
	 * them. */
	if (irqs_were_on)
		enable_irq();
	return;
}

/* Ups the semaphore.  If it was < 0, we need to wake up someone, which we do.
 * Returns TRUE if we woke someone, FALSE o/w (used for debugging in some
 * places).  If we need more control, we can implement a version of the old
 * __up_sem() again.  */
bool sem_up(struct semaphore *sem)
{
	struct kthread *kthread = 0;

	debug_lock_semlist();
	spin_lock(&sem->lock);
	if (sem->nr_signals++ < 0) {
		assert(!TAILQ_EMPTY(&sem->waiters));
		/* could do something with 'priority' here */
		kthread = TAILQ_FIRST(&sem->waiters);
		TAILQ_REMOVE(&sem->waiters, kthread, link);
	} else {
		assert(TAILQ_EMPTY(&sem->waiters));
	}
	debug_upped_sem(sem);
	spin_unlock(&sem->lock);
	debug_unlock_semlist();
	/* Note that once we call kthread_runnable(), we cannot touch the sem again.
	 * Some sems are on stacks.  The caller can touch sem, if it knows about the
	 * memory/usage of the sem.  Likewise, we can't touch the kthread either. */
	if (kthread) {
		kthread_runnable(kthread);
		return TRUE;
	}
	return FALSE;
}

bool sem_trydown_irqsave(struct semaphore *sem, int8_t *irq_state)
{
	bool ret;
	disable_irqsave(irq_state);
	ret = sem_trydown(sem);
	enable_irqsave(irq_state);
	return ret;
}

void sem_down_irqsave(struct semaphore *sem, int8_t *irq_state)
{
	disable_irqsave(irq_state);
	sem_down(sem);
	enable_irqsave(irq_state);
}

bool sem_up_irqsave(struct semaphore *sem, int8_t *irq_state)
{
	bool retval;
	disable_irqsave(irq_state);
	retval = sem_up(sem);
	enable_irqsave(irq_state);
	return retval;
}

/* Sem debugging */

#ifdef CONFIG_SEMAPHORE_DEBUG
struct semaphore_tailq sems_with_waiters =
                       TAILQ_HEAD_INITIALIZER(sems_with_waiters);
/* The lock ordering is sems_with_waiters_lock -> any_sem_lock */
spinlock_t sems_with_waiters_lock = SPINLOCK_INITIALIZER_IRQSAVE;

static void debug_lock_semlist(void)
{
	spin_lock_irqsave(&sems_with_waiters_lock);
}

static void debug_unlock_semlist(void)
{
	spin_unlock_irqsave(&sems_with_waiters_lock);
}

/* this gets called any time we downed the sem, regardless of whether or not we
 * waited */
static void debug_downed_sem(struct semaphore *sem)
{
	sem->bt_pc = read_pc();
	sem->bt_fp = read_bp();
	sem->calling_core = core_id();
	if (TAILQ_EMPTY(&sem->waiters) || sem->is_on_list)
		return;
	TAILQ_INSERT_HEAD(&sems_with_waiters, sem, link);
	sem->is_on_list = TRUE;
}

/* Called when a sem is upped.  It may or may not have waiters, and it may or
 * may not be on the list. (we could up several times past 0). */
static void debug_upped_sem(struct semaphore *sem)
{
	if (TAILQ_EMPTY(&sem->waiters) && sem->is_on_list) {
		TAILQ_REMOVE(&sems_with_waiters, sem, link);
		sem->is_on_list = FALSE;
	}
}

#else

static void debug_lock_semlist(void)
{
	/* no debugging */
}

static void debug_unlock_semlist(void)
{
	/* no debugging */
}

static void debug_downed_sem(struct semaphore *sem)
{
	/* no debugging */
}

static void debug_upped_sem(struct semaphore *sem)
{
	/* no debugging */
}

#endif /* CONFIG_SEMAPHORE_DEBUG */

void print_sem_info(struct semaphore *sem)
{
	struct kthread *kth_i;
	/* Always safe to irqsave */
	spin_lock_irqsave(&sem->lock);
	printk("Semaphore %p has %d signals (neg = waiters)", sem, sem->nr_signals);
#ifdef CONFIG_SEMAPHORE_DEBUG
	printk(", recently downed on core %d with pc/frame %p %p\n",
	       sem->calling_core, sem->bt_pc, sem->bt_fp);
#else
	printk("\n");
#endif /* CONFIG_SEMAPHORE_DEBUG */
	TAILQ_FOREACH(kth_i, &sem->waiters, link)
		printk("\tKthread %p (%s), proc %d (%p), sysc %p\n", kth_i, kth_i->name,
		       kth_i->proc ? kth_i->proc->pid : 0, kth_i->proc, kth_i->sysc);
	printk("\n");
	spin_unlock_irqsave(&sem->lock);
}

void print_all_sem_info(void)
{
#ifdef CONFIG_SEMAPHORE_DEBUG
	struct semaphore *sem_i;
	printk("All sems with waiters:\n");
	spin_lock_irqsave(&sems_with_waiters_lock);
	TAILQ_FOREACH(sem_i, &sems_with_waiters, link)
		print_sem_info(sem_i);
	spin_unlock_irqsave(&sems_with_waiters_lock);
#else
	printk("Failed to print all sems: build with CONFIG_SEMAPHORE_DEBUG\n");
#endif
}

/* Condition variables, using semaphores and kthreads */
void cv_init(struct cond_var *cv)
{
	sem_init(&cv->sem, 0);
	cv->lock = &cv->internal_lock;
	spinlock_init(cv->lock);
	cv->nr_waiters = 0;
	cv->irq_okay = FALSE;
}

void cv_init_irqsave(struct cond_var *cv)
{
	sem_init_irqsave(&cv->sem, 0);
	cv->lock = &cv->internal_lock;
	spinlock_init_irqsave(cv->lock);
	cv->nr_waiters = 0;
	cv->irq_okay = TRUE;
}

void cv_init_with_lock(struct cond_var *cv, spinlock_t *lock)
{
	sem_init(&cv->sem, 0);
	cv->nr_waiters = 0;
	cv->lock = lock;
	cv->irq_okay = FALSE;
}

void cv_init_irqsave_with_lock(struct cond_var *cv, spinlock_t *lock)
{
	sem_init_irqsave(&cv->sem, 0);
	cv->nr_waiters = 0;
	cv->lock = lock;
	cv->irq_okay = TRUE;
}

void cv_lock(struct cond_var *cv)
{
	spin_lock(cv->lock);
}

void cv_unlock(struct cond_var *cv)
{
	spin_unlock(cv->lock);
}

void cv_lock_irqsave(struct cond_var *cv, int8_t *irq_state)
{
	disable_irqsave(irq_state);
	cv_lock(cv);
}

void cv_unlock_irqsave(struct cond_var *cv, int8_t *irq_state)
{
	cv_unlock(cv);
	enable_irqsave(irq_state);
}

/* Helper to clarify the wait/signalling code */
static int nr_sem_waiters(struct semaphore *sem)
{
	int retval;
	retval = 0 - sem->nr_signals;
	assert(retval >= 0);
	return retval;
}

/* Comes in locked.  Note we don't mess with enabling/disabling irqs.  The
 * initial cv_lock would have disabled irqs (if applicable), and we don't mess
 * with that setting at all. */
void cv_wait_and_unlock(struct cond_var *cv)
{
	unsigned long nr_prev_waiters;
	nr_prev_waiters = cv->nr_waiters++;
	spin_unlock(cv->lock);
	/* Wait til our turn.  This forces an ordering of all waiters such that the
	 * order in which they wait is the order in which they down the sem. */
	while (nr_prev_waiters != nr_sem_waiters(&cv->sem))
		cpu_relax();
	printd("core %d, sees nr_sem_waiters: %d, cv_nr_waiters %d\n",
	       core_id(), nr_sem_waiters(&cv->sem), cv->nr_waiters);
	/* Atomically sleeps and 'unlocks' the next kthread from its busy loop (the
	 * one right above this), when it changes the sems nr_signals/waiters. */
	sem_down(&cv->sem);
}

/* Comes in locked.  Note cv_lock does not disable irqs.   They should still be
 * disabled from the initial cv_lock_irqsave(). */
void cv_wait(struct cond_var *cv)
{
	cv_wait_and_unlock(cv);
	if (cv->irq_okay)
		assert(!irq_is_enabled());
	cv_lock(cv);
}

/* Helper, wakes exactly one, and there should have been at least one waiter. */
static void sem_wake_one(struct semaphore *sem)
{
	struct kthread *kthread;

	/* these locks will be irqsaved if the CV is irqsave (only need the one) */
	debug_lock_semlist();
	spin_lock(&sem->lock);
	assert(sem->nr_signals < 0);
	sem->nr_signals++;
	kthread = TAILQ_FIRST(&sem->waiters);
	TAILQ_REMOVE(&sem->waiters, kthread, link);
	debug_upped_sem(sem);
	spin_unlock(&sem->lock);
	debug_unlock_semlist();
	kthread_runnable(kthread);
}

void __cv_signal(struct cond_var *cv)
{
	/* Can't short circuit this stuff.  We need to make sure any waiters that
	 * made it past upping the cv->nr_waiters has also downed the sem.
	 * Otherwise we muck with nr_waiters, which could break the ordering
	 * required by the waiters.  We also need to lock while making this check,
	 * o/w a new waiter can slip in after our while loop. */
	while (cv->nr_waiters != nr_sem_waiters(&cv->sem))
		cpu_relax();
	if (cv->nr_waiters) {
		cv->nr_waiters--;
		sem_wake_one(&cv->sem);
	}
}

void __cv_broadcast(struct cond_var *cv)
{
	while (cv->nr_waiters != nr_sem_waiters(&cv->sem))
		cpu_relax();
	while (cv->nr_waiters) {
		cv->nr_waiters--;
		sem_wake_one(&cv->sem);
	}
}

void cv_signal(struct cond_var *cv)
{
	spin_lock(cv->lock);
	__cv_signal(cv);
	spin_unlock(cv->lock);
}

void cv_broadcast(struct cond_var *cv)
{
	spin_lock(cv->lock);
	__cv_broadcast(cv);
	spin_unlock(cv->lock);
}

void cv_signal_irqsave(struct cond_var *cv, int8_t *irq_state)
{
	disable_irqsave(irq_state);
	cv_signal(cv);
	enable_irqsave(irq_state);
}

void cv_broadcast_irqsave(struct cond_var *cv, int8_t *irq_state)
{
	disable_irqsave(irq_state);
	cv_broadcast(cv);
	enable_irqsave(irq_state);
}

/* Helper, aborts and releases a CLE.  dereg_ spinwaits on abort_in_progress.
 * This can throw a PF */
static void __abort_and_release_cle(struct cv_lookup_elm *cle)
{
	int8_t irq_state = 0;
	/* At this point, we have a handle on the syscall that we want to abort (via
	 * the cle), and we know none of the memory will disappear on us (deregers
	 * wait on the flag).  So we'll signal ABORT, which rendez will pick up next
	 * time it is awake.  Then we make sure it is awake with a broadcast. */
	atomic_or(&cle->sysc->flags, SC_ABORT);
	cmb();	/* flags write before signal; atomic op provided CPU mb */
	cv_broadcast_irqsave(cle->cv, &irq_state);
	cmb();	/* broadcast writes before abort flag; atomic op provided CPU mb */
	atomic_dec(&cle->abort_in_progress);
}

/* Attempts to abort p's sysc.  It will only do so if the sysc lookup succeeds,
 * so we can handle "guesses" for syscalls that might not be sleeping.  This
 * style of "do it if you know you can" is the best way here - anything else
 * runs into situations where you don't know if the memory is safe to touch or
 * not (we're doing a lookup via pointer address, and only dereferencing if that
 * succeeds).  Even something simple like letting userspace write SC_ABORT is
 * very hard for them, since they don't know a sysc's state for sure (under the
 * current system).
 *
 * Here are the rules:
 * - if you're flagged SC_ABORT, you don't sleep
 * - if you sleep, you're on the list
 * - if you are on the list or abort_in_progress is set, CV is signallable, and
 *   all the memory for CLE is safe */
bool abort_sysc(struct proc *p, struct syscall *sysc)
{
	ERRSTACK(1);
	struct cv_lookup_elm *cle;
	int8_t irq_state = 0;

	spin_lock_irqsave(&p->abort_list_lock);
	TAILQ_FOREACH(cle, &p->abortable_sleepers, link) {
		if (cle->sysc == sysc) {
			/* Note: we could have multiple aborters, so we need to use a
			 * numeric refcnt instead of a flag. */
			atomic_inc(&cle->abort_in_progress);
			break;
		}
	}
	spin_unlock_irqsave(&p->abort_list_lock);
	if (!cle)
		return FALSE;
	if (!waserror())	/* discard error */
		__abort_and_release_cle(cle);
	poperror();
	return TRUE;
}

/* This will abort any abortables at the time the call was started for which
 * should_abort(cle, arg) returns true.  New abortables could be registered
 * concurrently.  The original for this is proc_destroy(), so DYING will be set,
 * and new abortables will quickly abort and dereg when they see their proc is
 * DYING. */
static int __abort_all_sysc(struct proc *p,
                            bool (*should_abort)(struct cv_lookup_elm*, void*),
                            void *arg)
{
	ERRSTACK(1);
	struct cv_lookup_elm *cle;
	int8_t irq_state = 0;
	struct cv_lookup_tailq abortall_list;
	uintptr_t old_proc = switch_to(p);
	int ret = 0;

	/* Concerns: we need to not remove them from their original list, since
	 * concurrent wake ups will cause a dereg, which will remove from the list.
	 * We also can't touch freed memory, so we need a refcnt to keep cles
	 * around. */
	TAILQ_INIT(&abortall_list);
	spin_lock_irqsave(&p->abort_list_lock);
	TAILQ_FOREACH(cle, &p->abortable_sleepers, link) {
		if (!should_abort(cle, arg))
			continue;
		atomic_inc(&cle->abort_in_progress);
		TAILQ_INSERT_HEAD(&abortall_list, cle, abortall_link);
		ret++;
	}
	spin_unlock_irqsave(&p->abort_list_lock);
	if (!waserror()) { /* discard error */
		TAILQ_FOREACH(cle, &abortall_list, abortall_link)
			__abort_and_release_cle(cle);
	}
	poperror();
	switch_back(p, old_proc);
	return ret;
}

static bool always_abort(struct cv_lookup_elm *cle, void *arg)
{
	return TRUE;
}

void abort_all_sysc(struct proc *p)
{
	__abort_all_sysc(p, always_abort, 0);
}

/* cle->sysc could be a bad pointer.  we can either use copy_from_user (btw,
 * we're already in their addr space) or we can use a waserror in
 * __abort_all_sysc().  Both options are fine.  I went with it here for a couple
 * reasons.  It is only this abort function pointer that accesses sysc, though
 * that could change.  Our syscall aborting isn't plugged into a broader error()
 * handler yet, which means we'd want to poperror instead of nexterror in
 * __abort_all_sysc, and that would required int ret getting a volatile flag. */
static bool sysc_uses_fd(struct cv_lookup_elm *cle, void *fd)
{
	struct syscall local_sysc;
	int err;

	err = copy_from_user(&local_sysc, cle->sysc, sizeof(struct syscall));
	/* Trigger an abort on error */
	if (err)
		return TRUE;
	return syscall_uses_fd(&local_sysc, (int)(long)fd);
}

int abort_all_sysc_fd(struct proc *p, int fd)
{
	return __abort_all_sysc(p, sysc_uses_fd, (void*)(long)fd);
}

/* Being on the abortable list means that the CLE, KTH, SYSC, and CV are valid
 * memory.  The lock ordering is {CV lock, list_lock}.  Callers to this *will*
 * have CV held.  This is done to avoid excessive locking in places like
 * rendez_sleep, which want to check the condition before registering. */
void __reg_abortable_cv(struct cv_lookup_elm *cle, struct cond_var *cv)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	cle->cv = cv;
	cle->kthread = pcpui->cur_kthread;
	/* Could be a ktask.  Can build in support for aborting these later */
	if (is_ktask(cle->kthread)) {
		cle->sysc = 0;
		return;
	}
	cle->sysc = cle->kthread->sysc;
	cle->proc = pcpui->cur_proc;
	atomic_init(&cle->abort_in_progress, 0);
	spin_lock_irqsave(&cle->proc->abort_list_lock);
	TAILQ_INSERT_HEAD(&cle->proc->abortable_sleepers, cle, link);
	spin_unlock_irqsave(&cle->proc->abort_list_lock);
}

/* We're racing with the aborter too, who will hold the flag in cle to protect
 * its ref on our cle.  While the lock ordering is CV, list, callers to this
 * must *not* have the cv lock held.  The reason is this waits on a successful
 * abort_sysc, which is trying to cv_{signal,broadcast}, which could wait on the
 * CV lock.  So if we hold the CV lock, we can deadlock (circular dependency).*/
void dereg_abortable_cv(struct cv_lookup_elm *cle)
{
	if (is_ktask(cle->kthread))
		return;
	assert(cle->proc);
	spin_lock_irqsave(&cle->proc->abort_list_lock);
	TAILQ_REMOVE(&cle->proc->abortable_sleepers, cle, link);
	spin_unlock_irqsave(&cle->proc->abort_list_lock);
	/* If we won the race and yanked it out of the list before abort claimed it,
	 * this will already be FALSE. */
	while (atomic_read(&cle->abort_in_progress))
		cpu_relax();
}

/* Helper to sleepers to know if they should abort or not.  I'll probably extend
 * this with things for ktasks in the future. */
bool should_abort(struct cv_lookup_elm *cle)
{
	struct syscall local_sysc;
	int err;

	if (is_ktask(cle->kthread))
		return FALSE;
	if (cle->proc && (cle->proc->state == PROC_DYING))
		return TRUE;
	if (cle->sysc) {
		assert(cle->proc && (cle->proc == current));
		err = copy_from_user(&local_sysc, cle->sysc,
		                     offsetof(struct syscall, flags) +
		                     sizeof(cle->sysc->flags));
		/* just go ahead and abort if there was an error */
		if (err || (atomic_read(&local_sysc.flags) & SC_ABORT))
			return TRUE;
	}
	return FALSE;
}

/* Sometimes the kernel needs to switch out of process context and into a
 * 'process-less' kernel thread.  This is basically a ktask.  We use this mostly
 * when performing file ops as the kernel.  It's nasty, and all uses of this
 * probably should be removed.  (TODO: KFOP). */
uintptr_t switch_to_ktask(void)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct kthread *kth = pcpui->cur_kthread;

	if (is_ktask(kth))
		return 0;
	/* We leave the SAVE_ADDR_SPACE flag on.  Now we're basically a ktask that
	 * cares about its addr space, since we need to return to it (not that we're
	 * leaving). */
	kth->flags |= KTH_IS_KTASK;
	return 1;
}

void switch_back_from_ktask(uintptr_t old_ret)
{
	struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
	struct kthread *kth = pcpui->cur_kthread;

	if (old_ret)
		kth->flags &= ~KTH_IS_KTASK;
}
