/*
 * Copyright (c) International Business Machines Corp., 2009
 * Some wrappers for clone functionality.  Thrown together by Serge Hallyn
 * <serue@us.ibm.com> based on existing clone usage in ltp.
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#ifndef _GNU_SOURCE
# define _GNU_SOURCE
#endif

#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <sched.h>
#include <stdarg.h>
#include "config.h"
#include "tst_clone.h"

#undef clone			/* we want to use clone() */

/*
 * The ia64 port has never included a prototype for __clone2(). It was updated
 * to take eight parameters in glibc commit:
 *
 * commit 625f22fc7f8e0d61e3e6cff2c65468b91dbad426
 * Author: Ulrich Drepper <drepper@redhat.com>
 * Date:   Mon Mar 3 19:53:27 2003 +0000
 *
 * The first release that contained this commit was glibc-2.3.3 which is old
 * enough to assume that __clone2() takes eight parameters.
 */
#if defined(__ia64__)
extern int __clone2(int (*fn) (void *arg), void *child_stack_base,
                    size_t child_stack_size, int flags, void *arg,
                    pid_t *parent_tid, void *tls, pid_t *child_tid);
#endif

#ifndef CLONE_SUPPORTS_7_ARGS
# define clone(fn, stack, flags, arg, ptid, tls, ctid) \
         clone(fn, stack, flags, arg)
#endif

/*
 * ltp_clone: wrapper for clone to hide the architecture dependencies.
 *   1. hppa takes bottom of stack and no stacksize (stack grows up)
 *   2. __ia64__ takes bottom of stack and uses clone2
 *   3. all others take top of stack (stack grows down)
 */
static int
ltp_clone_(unsigned long flags, int (*fn)(void *arg), void *arg,
	   size_t stack_size, void *stack, pid_t *ptid, void *tls, pid_t *ctid)
{
	int ret;

#if defined(__ia64__)
	ret = __clone2(fn, stack, stack_size, flags, arg, ptid, tls, ctid);
#else
# if defined(__hppa__) || defined(__metag__)
	/*
	 * These arches grow their stack up, so don't need to adjust the base.
	 * XXX: This should be made into a runtime test.
	 */
# else
	/*
	 * For archs where stack grows downwards, stack points to the topmost
	 * address of the memory space set up for the child stack.
	 */
	if (stack)
		stack += stack_size;
# endif

	ret = clone(fn, stack, flags, arg, ptid, tls, ctid);
#endif

	return ret;
}

int ltp_clone(unsigned long flags, int (*fn)(void *arg), void *arg,
              size_t stack_size, void *stack)
{
	return ltp_clone_(flags, fn, arg, stack_size, stack, NULL, NULL, NULL);
}

int ltp_clone7(unsigned long flags, int (*fn)(void *arg), void *arg,
               size_t stack_size, void *stack, ...)
{
	pid_t *ptid, *ctid;
	void *tls;
	va_list arg_clone;

	va_start(arg_clone, stack);
	ptid = va_arg(arg_clone, pid_t *);
	tls = va_arg(arg_clone, void *);
	ctid = va_arg(arg_clone, pid_t *);
	va_end(arg_clone);

#ifdef CLONE_SUPPORTS_7_ARGS
	return ltp_clone_(flags, fn, arg, stack_size, stack, ptid, tls, ctid);
#else
	errno = ENOSYS;
	return -1;
#endif
}

/*
 * ltp_alloc_stack: allocate stack of size 'size', that is sufficiently
 * aligned for all arches. User is responsible for freeing allocated
 * memory.
 * Returns pointer to new stack. On error, returns NULL with errno set.
 */
void *ltp_alloc_stack(size_t size)
{
	void *ret = NULL;
	int err;

	err = posix_memalign(&ret, 64, size);
	if (err)
		errno = err;

	return ret;
}

/*
 * ltp_clone_alloc: also does the memory allocation for clone with a
 * caller-specified size.
 */
int
ltp_clone_alloc(unsigned long clone_flags, int (*fn) (void *arg), void *arg,
		 size_t stack_size)
{
	void *stack;
	int ret;
	int saved_errno;

	stack = ltp_alloc_stack(stack_size);
	if (stack == NULL)
		return -1;

	ret = ltp_clone(clone_flags, fn, arg, stack_size, stack);

	if (ret == -1) {
		saved_errno = errno;
		free(stack);
		errno = saved_errno;
	}

	return ret;
}

/*
 * ltp_clone_quick: calls ltp_clone_alloc with predetermined stack size.
 * Experience thus far suggests that one page is often insufficient,
 * while 6*getpagesize() seems adequate.
 */
int ltp_clone_quick(unsigned long clone_flags, int (*fn) (void *arg), void *arg)
{
	size_t stack_size = getpagesize() * 6;

	return ltp_clone_alloc(clone_flags, fn, arg, stack_size);
}
