/*
 * 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 "test.h"

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

#if defined (__s390__) || defined(__s390x__)
#define clone __clone
extern int __clone(int (void *), void *, int, void *);
#elif defined(__ia64__)
#define clone2 __clone2

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

/*
 * 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)
 */
int
ltp_clone(unsigned long clone_flags, int (*fn) (void *arg), void *arg,
	  size_t stack_size, void *stack)
{
	int ret;

#if defined(__hppa__) || defined(__metag__)
	ret = clone(fn, stack, clone_flags, arg);
#elif defined(__ia64__)
	ret = clone2(fn, stack, stack_size, clone_flags, arg, NULL, NULL, NULL);
#else
	/*
	 * For archs where stack grows downwards, stack points to the topmost
	 * address of the memory space set up for the child stack.
	 */
	ret = clone(fn, (stack ? stack + stack_size : NULL), clone_flags, arg);
#endif

	return ret;
}

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

	stack = malloc(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_malloc 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_malloc(clone_flags, fn, arg, stack_size);
}
