0
+ − 1
+ − 2 /* Taken with thanks from LinuxThreads 0.6 */
+ − 3
+ − 4 /* This is no longer necessary with glibc-2.1, which has it's own clone() */
+ − 5 #ifdef linux
+ − 6 /* Look to see if glibc is available, and if so, what version */
+ − 7 #include <features.h>
+ − 8
+ − 9 #if (__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
+ − 10 #define HAVE_CLONE
+ − 11 #endif /* glibc 2.1 or newer */
+ − 12 #endif /* linux */
+ − 13
+ − 14 #if defined(linux) && !defined(SDL_USE_PTHREADS) && !defined(HAVE_CLONE)
+ − 15
+ − 16 #if defined(__i386__)
+ − 17 /************************************************************************/
+ − 18 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ − 19 Contributed by Richard Henderson (rth@tamu.edu)
+ − 20
+ − 21 The GNU C Library is free software; you can redistribute it and/or
+ − 22 modify it under the terms of the GNU Library General Public License as
+ − 23 published by the Free Software Foundation; either version 2 of the
+ − 24 License, or (at your option) any later version.
+ − 25
+ − 26 The GNU C Library is distributed in the hope that it will be useful,
+ − 27 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 28 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ − 29 Library General Public License for more details.
+ − 30
+ − 31 You should have received a copy of the GNU Library General Public
+ − 32 License along with the GNU C Library; see the file COPYING.LIB. If
+ − 33 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+ − 34
+ − 35 #ifdef SAVE_RCSID
+ − 36 static char rcsid =
+ − 37 "@(#) $Id$";
+ − 38 #endif
+ − 39 Cambridge, MA 02139, USA. */
+ − 40
+ − 41 /* clone() is even more special than fork() as it mucks with stacks
+ − 42 and invokes a function in the right context after its all over. */
+ − 43
+ − 44 #include <asm/errno.h>
+ − 45 #include <asm/unistd.h>
+ − 46
+ − 47 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+ − 48
+ − 49 .text
+ − 50 .align 4
+ − 51 .globl __clone
+ − 52 .type __clone,@function
+ − 53 .weak clone
+ − 54 clone = __clone
+ − 55 __clone:
+ − 56 /* Sanity check arguments. */
+ − 57 movl $-EINVAL,%eax
+ − 58 movl 4(%esp),%ecx /* no NULL function pointers */
+ − 59 testl %ecx,%ecx
+ − 60 jz syscall_error
+ − 61 movl 8(%esp),%ecx /* no NULL stack pointers */
+ − 62 testl %ecx,%ecx
+ − 63 jz syscall_error
+ − 64
+ − 65 /* Insert the argument onto the new stack. */
+ − 66 subl $8,%ecx
+ − 67 movl 16(%esp),%eax
+ − 68 movl %eax,4(%ecx)
+ − 69
+ − 70 /* Save the function pointer as the zeroth argument. */
+ − 71 /* It will be popped off in the child in the ebx frobbing below. */
+ − 72 movl 4(%esp),%eax
+ − 73 movl %eax,0(%ecx)
+ − 74
+ − 75 /* Do the system call */
+ − 76 pushl %ebx
+ − 77 movl 16(%esp),%ebx
+ − 78 movl $__NR_clone,%eax
+ − 79 int $0x80
+ − 80 popl %ebx
+ − 81
+ − 82 test %eax,%eax
+ − 83 jl syscall_error
+ − 84 jz thread_start
+ − 85
+ − 86 ret
+ − 87
+ − 88 syscall_error:
+ − 89 negl %eax
+ − 90 pushl %eax
+ − 91 #ifdef __PIC__
+ − 92 call __errno_location@PLT
+ − 93 #else
+ − 94 call __errno_location
+ − 95 #endif
+ − 96 popl 0(%eax)
+ − 97 movl $-1, %eax
+ − 98 ret
+ − 99
+ − 100 thread_start:
+ − 101 subl %ebp,%ebp /* terminate the stack frame */
+ − 102 call *%ebx
+ − 103 pushl %eax
+ − 104 #ifdef __PIC__
+ − 105 call _exit@PLT
+ − 106 #else
+ − 107 call _exit
+ − 108 #endif
+ − 109 /************************************************************************/
+ − 110 #elif defined(sparc)
+ − 111 /************************************************************************/
+ − 112 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
+ − 113 Contributed by Miguel de Icaza (miguel@nuclecu.unam.mx)
+ − 114 Based on code written for the Intel by Richard
+ − 115 Henderson (rth@tamu.edu)
+ − 116
+ − 117 The GNU C Library is free software; you can redistribute it and/or
+ − 118 modify it under the terms of the GNU Library General Public License as
+ − 119 published by the Free Software Foundation; either version 2 of the
+ − 120 License, or (at your option) any later version.
+ − 121
+ − 122 The GNU C Library is distributed in the hope that it will be useful,
+ − 123 but WITHOUT ANY WARRANTY; without even the implied warranty of
+ − 124 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ − 125 Library General Public License for more details.
+ − 126
+ − 127 You should have received a copy of the GNU Library General Public
+ − 128 License along with the GNU C Library; see the file COPYING.LIB. If
+ − 129 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+ − 130 Cambridge, MA 02139, USA. */
+ − 131
+ − 132 /* clone() is even more special than fork() as it mucks with stacks
+ − 133 and invokes a function in the right context after its all over. */
+ − 134
+ − 135 #include <asm/errno.h>
+ − 136 #include <asm/unistd.h>
+ − 137
+ − 138 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */
+ − 139
+ − 140 .text
+ − 141 .align 4
+ − 142 .globl __clone
+ − 143 .type __clone,@function
+ − 144 .weak clone
+ − 145 clone = __clone
+ − 146 __clone:
+ − 147 save %sp,-96,%sp
+ − 148 /* sanity check arguments */
+ − 149 tst %i0
+ − 150 be __clone_syscall_error
+ − 151 tst %i1
+ − 152 be __clone_syscall_error
+ − 153 nop
+ − 154
+ − 155 /* Do the system call */
+ − 156 mov %i1,%o1
+ − 157 mov %i2,%o0
+ − 158 set __NR_clone,%g1
+ − 159 ta 0x10
+ − 160 bcs __clone_syscall_error
+ − 161 tst %o1
+ − 162 bne __thread_start
+ − 163 nop
+ − 164 mov %o0,%i0
+ − 165 ret
+ − 166 restore
+ − 167
+ − 168 __clone_syscall_error:
+ − 169 call __errno_location
+ − 170 set EINVAL,%i0
+ − 171 st %i0,[%o0]
+ − 172 mov -1,%i0
+ − 173 ret
+ − 174 restore
+ − 175
+ − 176 __thread_start:
+ − 177 call %i0
+ − 178 mov %i3,%o0
+ − 179 call _exit,0
+ − 180 nop
+ − 181 /************************************************************************/
+ − 182 #else
+ − 183 #error "Unknown Linux architecture"
+ − 184 #endif
+ − 185
+ − 186 #endif /* Linux && ! SDL_USE_PTHREADS */