/* Copyright (c) 2015 Google, Inc.
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * thread0_sched: a basic scheduler for thread0, used by SCPs without a
 * multithreaded 2LS linked in.
 *
 * This is closely coupled with uthread.c */

#include <ros/arch/membar.h>
#include <parlib/arch/atomic.h>
#include <parlib/parlib.h>
#include <parlib/vcore.h>
#include <parlib/uthread.h>
#include <parlib/event.h>
#include <parlib/arch/trap.h>
#include <parlib/ros_debug.h>
#include <stdlib.h>
#include <sys/fork_cb.h>

static void thread0_sched_init(void);
static void thread0_sched_entry(void);
static void thread0_thread_blockon_sysc(struct uthread *uthread, void *sysc);
static void thread0_thread_refl_fault(struct uthread *uth,
                                      struct user_context *ctx);
static void thread0_thread_runnable(struct uthread *uth);
static void thread0_thread_has_blocked(struct uthread *uth, int flags);
static void thread0_thread_exited(struct uthread *uth);
static struct uthread *thread0_thread_create(void *(*func)(void *), void *arg);
static void thread0_got_posix_signal(int sig_nr, struct siginfo *info);
static void thread0_sync_init(uth_sync_t *s);
static void thread0_sync_destroy(uth_sync_t *s);
static void thread0_sync_enqueue(struct uthread *uth, uth_sync_t *s);
static struct uthread *thread0_sync_get_next(uth_sync_t *s);
static bool thread0_sync_get_uth(uth_sync_t *s, struct uthread *uth);
static void thread0_sync_swap(uth_sync_t *a, uth_sync_t *b);
static bool thread0_sync_is_empty(uth_sync_t *s);

/* externed into uthread.c */
struct schedule_ops thread0_2ls_ops = {
	.sched_init = thread0_sched_init,
	.sched_entry = thread0_sched_entry,
	.thread_blockon_sysc = thread0_thread_blockon_sysc,
	.thread_refl_fault = thread0_thread_refl_fault,
	.thread_runnable = thread0_thread_runnable,
	.thread_paused = thread0_thread_runnable,
	.thread_has_blocked = thread0_thread_has_blocked,
	.thread_exited = thread0_thread_exited,
	.thread_create = thread0_thread_create,
	.got_posix_signal = thread0_got_posix_signal,
	.sync_init = thread0_sync_init,
	.sync_destroy = thread0_sync_destroy,
	.sync_enqueue = thread0_sync_enqueue,
	.sync_get_next = thread0_sync_get_next,
	.sync_get_uth = thread0_sync_get_uth,
	.sync_swap = thread0_sync_swap,
	.sync_is_empty = thread0_sync_is_empty,
};

struct schedule_ops *sched_ops __attribute__((weak)) = &thread0_2ls_ops;

/* externed into uthread.c */
struct uthread *thread0_uth;

/* Our thread0 is actually allocated in uthread as just a struct uthread, so we
 * don't actually attach this mgmt info to it.  But since we just have one
 * thread, it doesn't matter. */
struct thread0_info {
	bool				is_blocked;
};
static struct thread0_info thread0_info;
static struct event_queue *sysc_evq;

void thread0_handle_syscall(struct event_msg *ev_msg,
                            unsigned int ev_type, void *data)
{
	thread0_info.is_blocked = FALSE;
}

static void thread0_pre_fork(void)
{
}

static void thread0_post_fork(pid_t ret)
{
}

void thread0_sched_init(void)
{
	int ret;

	ret = posix_memalign((void**)&thread0_uth, __alignof__(struct uthread),
	                     sizeof(struct uthread));
	assert(!ret);
	/* aggressively 0 for bugs*/
	memset(thread0_uth, 0, sizeof(struct uthread));
	memset(&thread0_info, 0, sizeof(thread0_info));
	/* we don't care about the message, so don't bother with a UCQ */
	sysc_evq = get_eventq(EV_MBOX_BITMAP);
	sysc_evq->ev_flags = EVENT_INDIR | EVENT_WAKEUP;
	uthread_2ls_init(thread0_uth, thread0_handle_syscall, NULL);
	pre_fork_2ls = thread0_pre_fork;
	post_fork_2ls = thread0_post_fork;
}

/* Thread0 scheduler ops (for processes that haven't linked in a full 2LS) */
static void thread0_sched_entry(void)
{
	/* TODO: support signal handling whenever we run a uthread */
	if (current_uthread) {
		uthread_prep_pending_signals(current_uthread);
		run_current_uthread();
		assert(0);
	}
	while (1) {
		if (!thread0_info.is_blocked) {
			uthread_prep_pending_signals(thread0_uth);
			run_uthread(thread0_uth);
			assert(0);
		}
		sys_yield(FALSE);
		handle_events(0);
	}
}

static void thread0_thread_blockon_sysc(struct uthread *uthread, void *arg)
{
	struct syscall *sysc = (struct syscall*)arg;

	thread0_thread_has_blocked(uthread, 0);
	if (!register_evq(sysc, sysc_evq))
		thread0_thread_runnable(uthread);
}

static void refl_error(struct uthread *uth, unsigned int trap_nr,
                       unsigned int err, unsigned long aux)
{
	printf("Thread has unhandled fault: %d, err: %d, aux: %p\n",
	       trap_nr, err, aux);
	/* Note that uthread.c already copied out our ctx into the uth
	 * struct */
	print_user_context(&uth->u_ctx);
	printf("Turn on printx to spew unhandled, malignant trap info\n");
	exit(-1);
}

static bool handle_page_fault(struct uthread *uth, unsigned int err,
                              unsigned long aux)
{
	if (!(err & PF_VMR_BACKED))
		return FALSE;
	syscall_async(&uth->local_sysc, SYS_populate_va, aux, 1);
	__block_uthread_on_async_sysc(uth);
	return TRUE;
}

static void thread0_thread_refl_fault(struct uthread *uth,
                                      struct user_context *ctx)
{
	unsigned int trap_nr = __arch_refl_get_nr(ctx);
	unsigned int err = __arch_refl_get_err(ctx);
	unsigned long aux = __arch_refl_get_aux(ctx);

	assert(ctx->type == ROS_HW_CTX);
	switch (trap_nr) {
	case HW_TRAP_PAGE_FAULT:
		if (!handle_page_fault(uth, err, aux))
			refl_error(uth, trap_nr, err, aux);
		break;
	default:
		refl_error(uth, trap_nr, err, aux);
	}
}

static void thread0_thread_runnable(struct uthread *uth)
{
	thread0_info.is_blocked = FALSE;
}

static void thread0_thread_has_blocked(struct uthread *uth, int flags)
{
	assert(!thread0_info.is_blocked);
	thread0_info.is_blocked = TRUE;
}

/* Actually, a 2LS only needs to implement this if it calls
 * uth_2ls_thread_exit().  Keep it here to catch bugs. */
static void thread0_thread_exited(struct uthread *uth)
{
	assert(0);
}

static struct uthread *thread0_thread_create(void *(*func)(void *), void *arg)
{
	panic("Thread0 sched asked to create more threads!");
}

static void thread0_got_posix_signal(int sig_nr, struct siginfo *info)
{
	if (current_uthread)
		trigger_posix_signal(sig_nr, info, get_cur_uth_ctx());
	else
		trigger_posix_signal(sig_nr, info, &thread0_uth->u_ctx);
	/* Legacy single-threaded programs, which often use thread0, expect
	 * signals to interrupt their syscall.  For most 2LSes, we can't match a
	 * process-wide signal to a particular thread; the kernel knows nothing
	 * of threads, we're just receiving an event.  However, thread0 has only
	 * one thread. */
	if (thread0_uth->sysc)
		sys_abort_sysc(thread0_uth->sysc);
}

static void thread0_sync_init(uth_sync_t *s)
{
	memset(s, 0x5a, sizeof(uth_sync_t));
}

static void thread0_sync_destroy(uth_sync_t *s)
{
}

static void thread0_sync_enqueue(struct uthread *uth, uth_sync_t *s)
{
}

static struct uthread *thread0_sync_get_next(uth_sync_t *s)
{
	if (thread0_info.is_blocked) {
		/* Note we don't clear is_blocked.  Runnable does that, which
		 * should be called before the next get_next (since we have only
		 * one thread). */
		return thread0_uth;
	} else {
		return NULL;
	}
}

static bool thread0_sync_get_uth(uth_sync_t *s, struct uthread *uth)
{
	assert(uth == thread0_uth);
	if (thread0_info.is_blocked) {
		/* Note we don't clear is_blocked.  Runnable does that. */
		return TRUE;
	}
	return FALSE;
}

static void thread0_sync_swap(uth_sync_t *a, uth_sync_t *b)
{
}

static bool thread0_sync_is_empty(uth_sync_t *s)
{
	return !thread0_info.is_blocked;
}
