/*
 *  Copyright (C) 2007-2010 Lawrence Livermore National Security, LLC.
 *  Copyright (C) 2007 The Regents of the University of California.
 *  Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
 *  Written by Brian Behlendorf <behlendorf1@llnl.gov>.
 *  UCRL-CODE-235197
 *
 *  This file is part of the SPL, Solaris Porting Layer.
 *  For details, see <http://zfsonlinux.org/>.
 *
 *  The SPL 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.
 *
 *  The SPL 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 the SPL.  If not, see <http://www.gnu.org/licenses/>.
 *
 *  Solaris Porting Layer (SPL) Thread Implementation.
 */

#include <sys/thread.h>
#include <sys/kmem.h>
#include <sys/tsd.h>

/*
 * Thread interfaces
 */
typedef struct thread_priv_s {
	unsigned long tp_magic;		/* Magic */
	int tp_name_size;		/* Name size */
	char *tp_name;			/* Name (without _thread suffix) */
	void (*tp_func)(void *);	/* Registered function */
	void *tp_args;			/* Args to be passed to function */
	size_t tp_len;			/* Len to be passed to function */
	int tp_state;			/* State to start thread at */
	pri_t tp_pri;			/* Priority to start threat at */
} thread_priv_t;

static int
thread_generic_wrapper(void *arg)
{
	thread_priv_t *tp = (thread_priv_t *)arg;
	void (*func)(void *);
	void *args;

	ASSERT(tp->tp_magic == TP_MAGIC);
	func = tp->tp_func;
	args = tp->tp_args;
	set_current_state(tp->tp_state);
	set_user_nice((kthread_t *)current, PRIO_TO_NICE(tp->tp_pri));
	kmem_free(tp->tp_name, tp->tp_name_size);
	kmem_free(tp, sizeof (thread_priv_t));

	if (func)
		func(args);

	return (0);
}

void
__thread_exit(void)
{
	tsd_exit();
	complete_and_exit(NULL, 0);
	/* Unreachable */
}
EXPORT_SYMBOL(__thread_exit);

/*
 * thread_create() may block forever if it cannot create a thread or
 * allocate memory.  This is preferable to returning a NULL which Solaris
 * style callers likely never check for... since it can't fail.
 */
kthread_t *
__thread_create(caddr_t stk, size_t  stksize, thread_func_t func,
    const char *name, void *args, size_t len, proc_t *pp, int state, pri_t pri)
{
	thread_priv_t *tp;
	struct task_struct *tsk;
	char *p;

	/* Option pp is simply ignored */
	/* Variable stack size unsupported */
	ASSERT(stk == NULL);

	tp = kmem_alloc(sizeof (thread_priv_t), KM_PUSHPAGE);
	if (tp == NULL)
		return (NULL);

	tp->tp_magic = TP_MAGIC;
	tp->tp_name_size = strlen(name) + 1;

	tp->tp_name = kmem_alloc(tp->tp_name_size, KM_PUSHPAGE);
	if (tp->tp_name == NULL) {
		kmem_free(tp, sizeof (thread_priv_t));
		return (NULL);
	}

	strncpy(tp->tp_name, name, tp->tp_name_size);

	/*
	 * Strip trailing "_thread" from passed name which will be the func
	 * name since the exposed API has no parameter for passing a name.
	 */
	p = strstr(tp->tp_name, "_thread");
	if (p)
		p[0] = '\0';

	tp->tp_func  = func;
	tp->tp_args  = args;
	tp->tp_len   = len;
	tp->tp_state = state;
	tp->tp_pri   = pri;

	tsk = spl_kthread_create(thread_generic_wrapper, (void *)tp,
	    "%s", tp->tp_name);
	if (IS_ERR(tsk))
		return (NULL);

	wake_up_process(tsk);
	return ((kthread_t *)tsk);
}
EXPORT_SYMBOL(__thread_create);

/*
 * spl_kthread_create - Wrapper providing pre-3.13 semantics for
 * kthread_create() in which it is not killable and less likely
 * to return -ENOMEM.
 */
struct task_struct *
spl_kthread_create(int (*func)(void *), void *data, const char namefmt[], ...)
{
	struct task_struct *tsk;
	va_list args;
	char name[TASK_COMM_LEN];

	va_start(args, namefmt);
	vsnprintf(name, sizeof (name), namefmt, args);
	va_end(args);
	do {
		tsk = kthread_create(func, data, "%s", name);
		if (IS_ERR(tsk)) {
			if (signal_pending(current)) {
				clear_thread_flag(TIF_SIGPENDING);
				continue;
			}
			if (PTR_ERR(tsk) == -ENOMEM)
				continue;
			return (NULL);
		} else {
			return (tsk);
		}
	} while (1);
}
EXPORT_SYMBOL(spl_kthread_create);
