2 * Copyright (c) International Business Machines Corp., 2009
3 * Some wrappers for clone functionality. Thrown together by Serge Hallyn
4 * <serue@us.ibm.com> based on existing clone usage in ltp.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
14 * the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
26 #include <unistd.h> /* fork, getpid, sleep */
28 #include <stdlib.h> /* exit */
29 #include <sched.h> /* clone */
32 #undef clone /* we want to use clone() */
34 /* copied from several other files under ltp */
35 #if defined (__s390__) || (__s390x__)
37 extern int __clone(int(void*),void*,int,void*);
38 #elif defined(__ia64__)
39 #define clone2 __clone2
40 /* Prototype provided by David Mosberger */
41 extern int __clone2(int (*fn
) (void *arg
), void *child_stack_base
,
42 size_t child_stack_size
, int flags
, void *arg
,
43 pid_t
*parent_tid
, void *tls
, pid_t
*child_tid
);
46 /***********************************************************************
47 * ltp_clone: wrapper for clone to hide the architecture dependencies.
48 * 1. hppa takes bottom of stack and no stacksize (stack grows up)
49 * 2. __ia64__ takes bottom of stack and uses clone2
50 * 3. all others take top of stack (stack grows down)
51 ***********************************************************************/
53 ltp_clone(unsigned long clone_flags
, int (*fn
)(void *arg
), void *arg
,
54 size_t stack_size
, void *stack
)
59 ret
= clone(fn
, stack
, clone_flags
, arg
);
60 #elif defined(__ia64__)
61 ret
= clone2(fn
, stack
, stack_size
, clone_flags
, arg
, NULL
, NULL
, NULL
);
63 ret
= clone(fn
, (stack
? stack
+ stack_size
- 1 : NULL
),
70 /***********************************************************************
71 * ltp_clone_malloc: also does the memory allocation for clone with a
72 * caller-specified size.
73 ***********************************************************************/
75 ltp_clone_malloc(unsigned long clone_flags
, int (*fn
)(void *arg
), void *arg
,
79 void *stack
= malloc(stack_size
);
85 ret
= ltp_clone(clone_flags
, fn
, arg
, stack_size
, stack
);
96 /***********************************************************************
97 * ltp_clone_quick: calls ltp_clone_malloc with predetermined stack size.
98 * Experience thus far suggests that one page is often insufficient,
99 * while 4*getpagesize() seems adequate.
100 ***********************************************************************/
102 ltp_clone_quick(unsigned long clone_flags
, int (*fn
)(void *arg
), void *arg
)
104 size_t stack_size
= getpagesize() * 4;
106 return ltp_clone_malloc(clone_flags
, fn
, arg
, stack_size
);