/*
 * Copyright (c) 2013 The Chromium OS Authors.
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <common.h>
#include <errno.h>
#include <fdtdec.h>
#include <fthread.h>
#include <malloc.h>
#include <asm/global_data.h>

#include "fthread_priv.h"

DECLARE_GLOBAL_DATA_PTR;

/* thread library should only be initialized once */
static bool fthread_initialized;

/* Thread state printed information */
static const char * const fthread_state_names[] = {
	[FTHREAD_STATE_SCHEDULER] = "SCHEDULER",
	[FTHREAD_STATE_NEW] = "NEW",
	[FTHREAD_STATE_READY] = "READY",
	[FTHREAD_STATE_RUNNING] = "RUNNING",
	[FTHREAD_STATE_WAITING] = "WAITING",
	[FTHREAD_STATE_DEAD] = "DEAD"
};

int fthread_init(void)
{
	int err;

	if (fthread_initialized)
		return -EBUSY;

	debug("%s: enter\n", __func__);

	/* initilize the scheduler */
	fthread_scheduler_init();

	/* spawn the scheduler thread */
	err = fthread_spawn(fthread_scheduler, NULL, NULL, NULL, NULL,
			    FTHREAD_PRIO_MAX, "**SCHEDULER**",
			    FTHREAD_DEFAULT_STACKSIZE, &fthread_sched);
	if (err) {
		fthread_scheduler_kill();
		return err;
	}

	/* spawn the main thread, which should have a stack size of 0 */
	err = fthread_spawn(FTHREAD_MAIN_FUNC, NULL, NULL, NULL, NULL,
			    FTHREAD_PRIO_STD, "**main**", 0, &fthread_main);
	if (err) {
		fthread_scheduler_kill();
		return err;
	}

	fthread_initialized = true;

	/*
	 * We need to manually switch to the scheduler thread the first time to
	 * start threading.  Since the main thread is currently the only thread
	 * in the scheduler, we should come back immediately.  We also need to
	 * initialize fthread_current here so that the scheduler function is
	 * spawned correctly.
	 */
	fthread_current = fthread_sched;
	fthread_mctx_switch(fthread_main->mctx, fthread_sched->mctx);

	/* we will come right back to here after the scheduler initializes */
	debug("%s: exit\n", __func__);
	return 0;
}

int fthread_shutdown(void)
{
	if (!fthread_initialized)
		return -EPERM;
	if (fthread_current != fthread_main)
		return -EPERM;

	debug("%s: enter\n", __func__);
#ifdef CONFIG_FTHREAD_REPORT
	fthread_report();
#endif
	fthread_scheduler_kill();
	fthread_initialized = false;
	fthread_tcb_free(fthread_sched);
	fthread_tcb_free(fthread_main);

	debug("%s: exit\n", __func__);
	return 0;
}

void fthread_print_stats(struct fthread *t)
{
	/* Spawned time */
	print_grouped_ull(t->spawned_us, FTHREAD_REPORT_DIGITS);

	/* State */
	printf("%*s", FTHREAD_REPORT_DIGITS, fthread_state_names[t->state]);

	/* Running time */
	print_grouped_ull(t->running_us, FTHREAD_REPORT_DIGITS);

	/* Number of dispatches */
	print_grouped_ull(t->dispatches, FTHREAD_REPORT_DIGITS);

	/* Last time the thread ran */
	print_grouped_ull(t->lastran_us, FTHREAD_REPORT_DIGITS);

	/* Total sleep error */
	print_grouped_ull(t->err_us, FTHREAD_REPORT_DIGITS);

	/* Average sleep error */
	print_grouped_ull(t->num_sleeps == 0 ? 0 : t->err_us / t->num_sleeps,
			  FTHREAD_REPORT_DIGITS);

	/* Biggest sleep error */
	print_grouped_ull(t->maxerr_us, FTHREAD_REPORT_DIGITS);

	/* Name */
	printf("  %s\n", t->name);
}

void fthread_print_pqueue_stats(struct fthread_pqueue *q)
{
	struct fthread *t;

	for (t = fthread_pqueue_head(q); t != NULL;
	     t = fthread_pqueue_walk(q, t, FTHREAD_WALK_NEXT)) {
		fthread_print_stats(t);
	}
}

int fthread_report(void)
{
	unsigned long gdflags = gd->flags;

	if (!fthread_initialized)
		return -EPERM;

	/* Unsilence the console if necessary */
	if (fdtdec_get_config_int(gd->fdt_blob, "force-fthread-report", 0))
		gd->flags &= ~GD_FLG_SILENT;

	puts("Thread summary in microseconds:\n");
	printf("%*s%*s%*s%*s%*s%*s%*s%*s  %s\n",
	       FTHREAD_REPORT_NAME, "Spawned",
	       FTHREAD_REPORT_DIGITS, "State",
	       FTHREAD_REPORT_NAME, "Running",
	       FTHREAD_REPORT_NAME, "Dispatches",
	       FTHREAD_REPORT_NAME, "Lastran",
	       FTHREAD_REPORT_NAME, "Wait Err(us)",
	       FTHREAD_REPORT_NAME, "Avg Err(us)",
	       FTHREAD_REPORT_NAME, "Max Err(us)",
	       "Name");

	/* Print runtime information for each queue */
	fthread_print_pqueue_stats(&fthread_nq);
	fthread_print_pqueue_stats(&fthread_rq);
	fthread_print_pqueue_stats(&fthread_wq);
	fthread_print_pqueue_stats(&fthread_dq);

	/*
	 * The current thread and the scheduler will not be in any queue so we
	 * must explicitly print their runtime information
	 */
	fthread_print_stats(fthread_current);
	fthread_print_stats(fthread_sched);

	/* Restore global data flags */
	gd->flags = gdflags;

	return 0;
}

int fthread_tcb_alloc(unsigned int stacksize, struct fthread **threadp)
{
	struct fthread *t = malloc(sizeof(struct fthread));

	if (t == NULL)
		return -ENOMEM;

	t->stacksize = stacksize;
	t->stack = NULL;

	if (stacksize > 0) { /* stacksize == 0 => main thread */
		t->stack = malloc(stacksize);
		if (t->stack == NULL) {
			free(t);
			return -ENOMEM;
		}
	}

	t->mctx = fthread_mctx_alloc();
	if (t->mctx == NULL) {
		free(t->stack);
		free(t);
		return -ENOMEM;
	}

	*threadp = t;

	return 0;
}

void fthread_tcb_free(struct fthread *t)
{
	fthread_mctx_free(t->mctx);
	free(t->stack);
	free(t);
}

/**
 * fthread_spawn_helper() - Jump start a new thread of execution.
 */
static void fthread_spawn_helper(void)
{
	void *data;

	data = (*fthread_current->start_func)(fthread_current->start_arg);

	/* do an implicit exit with the return value */
	fthread_exit(data);
}

int fthread_spawn(void *(*func)(void *), void *arg, void (*pre_start)(void *),
		  void (*post_stop)(void *), void *context, int prio,
		  const char *name, size_t stacksize, struct fthread **threadp)
{
	unsigned long time;
	char *sk_addr_hi;
	struct fthread *t;
	int err;

	debug("%s: spawning thread \"%s\"\n", __func__, name);
	if (func == NULL)
		return -EINVAL;

	/* special case of the main thread */
	if (func == FTHREAD_MAIN_FUNC)
		func = NULL;

	if (fthread_tcb_alloc(stacksize, &t))
		return -ENOMEM;

	t->prio = prio;
	strncpy(t->name, name, FTHREAD_TCB_NAMELEN);

	/* initialize time points */
	time = fthread_get_current_time_us();
	t->spawned_us = time;
	t->lastran_us = time;
	t->running_us = 0;
	t->dispatches = 0;
	t->err_us = 0;
	t->maxerr_us = 0;
	t->num_sleeps = 0;

	/* initialize global state preserving functions */
	t->pre_start = pre_start;
	t->post_stop = post_stop;
	t->context = context;

	/* initialize starting and ending values */
	t->start_func = func;
	t->start_arg = arg;
	t->join_arg = NULL;

	/* initialize machine state */
	if (stacksize > 0) {	/* The main thread has stacksize == 0 */
		sk_addr_hi = t->stack + t->stacksize;
		err = fthread_mctx_set(t->mctx, fthread_spawn_helper, t->stack,
				       sk_addr_hi);
		if (err) {
			fthread_tcb_free(t);
			return err;
		}
	}

	/* Add the thread to the new queue so the scheduler will pick it up */
	if (func != fthread_scheduler) {
		t->state = FTHREAD_STATE_NEW;
		fthread_pqueue_insert(&fthread_nq, t->prio, t);
	}

	*threadp = t;
	debug("%s: exit\n", __func__);
	return 0;
}

inline void fthread_yield(void)
{
	debug("%s: thread \"%s\" giving up control to scheduler\n",
	      __func__, fthread_current->name);
	fthread_mctx_switch(fthread_current->mctx, fthread_sched->mctx);
	debug("%s: returning to thread \"%s\"\n",  __func__,
	      fthread_current->name);
}

unsigned long fthread_usleep(unsigned long waittime)
{
	unsigned long actualtime = waittime;
	unsigned long err;

	/*
	 * If U-Boot has not relocated or if fthread isn't initialized then
	 * don't do anything and just sleep
	 */
	if ((gd->flags & GD_FLG_RELOC) == 0 || !fthread_initialized) {
		__udelay(waittime);
	} else if (waittime != 0) {
		fthread_current->state = FTHREAD_STATE_WAITING;
		fthread_current->waitevent = FTHREAD_EVENT_SLEEP;
		fthread_current->ev_time = waittime;
		fthread_current->ev_tid = NULL;
		fthread_current->ev_func = NULL;
		fthread_yield();

		/* track the actual sleeping time and error */
		actualtime = fthread_sched->lastran_us -
			     fthread_current->lastran_us;
		err = actualtime - waittime;
		fthread_current->num_sleeps++;
		fthread_current->err_us += err;
		if (err > fthread_current->maxerr_us)
			fthread_current->maxerr_us = err;
	}

	return actualtime;
}

int fthread_join(struct fthread *tid, void **value)
{
	debug("%s: joining thread \"%s\"\n", __func__, tid->name);
	if (tid == NULL)
		return -EINVAL;
	if (tid == fthread_current)
		return -EDEADLK;

	if (tid->state != FTHREAD_STATE_DEAD) {
		fthread_current->state = FTHREAD_STATE_WAITING;
		fthread_current->waitevent = FTHREAD_EVENT_JOIN;
		fthread_current->ev_tid = tid;
		fthread_current->ev_time = 0;
		fthread_current->ev_func = NULL;
		fthread_yield();
	}

	if (value != NULL)
		*value = tid->join_arg;

#ifndef CONFIG_FTHREAD_REPORT
	/* Only delete joined threads if we aren't reporting stats */
	fthread_pqueue_delete(&fthread_dq, tid);
	fthread_tcb_free(tid);
#endif

	return 0;
}

/**
 * fthread_exit_main_cb() - Callback to check when main thread should exit
 *
 * Special predicate function to wait until @a fthread_main is the only thread
 * left in the system.  This function must be called from _within_ the scheduler
 * so that fthread_scheduler_eventmanager() can figure out whether or not to
 * wake up the main thread, which will then terminate the application.
 *
 * @return true if there is only one thread left in the system, false otherwise
 */
static int fthread_exit_main_cb(void)
{
	int count = 0;

	count += fthread_pqueue_length(&fthread_nq);
	count += fthread_pqueue_length(&fthread_rq);
	count += fthread_pqueue_length(&fthread_wq);

	if (count == 1) /* only the main thread is left */
		return true;
	else
		return false;
}

void fthread_exit(void *value)
{
	debug("%s: thread \"%s\" has terminated\n", __func__,
	      fthread_current->name);
	/*
	 * The main thread is special, because its termination would terminate
	 * the whole program, so we use a special predicate function event to
	 * wait until the main thread is the only thread left in the program,
	 * then cleanup and exit.
	 */
	if (fthread_current != fthread_main) {
		/*
		 * Mark the current thread as dead and switch to the scheduler,
		 * which will clean up after us.  Control should never return
		 */
		fthread_current->join_arg = value;
		fthread_current->state = FTHREAD_STATE_DEAD;
		debug("%s: switching from \"%s\" to scheduler\n",
		      __func__, fthread_current->name);
		fthread_yield();
	} else {
		if (!fthread_exit_main_cb()) {
			fthread_current->state = FTHREAD_STATE_WAITING;
			fthread_current->waitevent = FTHREAD_EVENT_FUNC;
			fthread_current->ev_func = fthread_exit_main_cb;
			fthread_current->ev_time = 0;
			fthread_current->ev_tid = NULL;
			fthread_yield();
		}

		fthread_shutdown();
	}
}
