diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 6 | ||||
-rw-r--r-- | linuxthreads/attr.c | 9 | ||||
-rw-r--r-- | linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S | 39 |
3 files changed, 46 insertions, 8 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog index cd5eb8e61f..5a86b94232 100644 --- a/linuxthreads/ChangeLog +++ b/linuxthreads/ChangeLog @@ -1,3 +1,9 @@ +2003-09-17 Philip Blundell <philb@gnu.org> + + * sysdeps/unix/sysv/linux/arm/vfork.S: Branch to fork if + libpthread is loaded. Elide backwards compatibility code when not + required. + 2003-09-17 Jakub Jelinek <jakub@redhat.com> * descr.h (manager_thread): Rename to... diff --git a/linuxthreads/attr.c b/linuxthreads/attr.c index a66eb72c27..687334ffdb 100644 --- a/linuxthreads/attr.c +++ b/linuxthreads/attr.c @@ -404,7 +404,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) # endif #endif +#ifdef USE_TLS if (attr->__stackaddr == NULL) +#else + if (descr == &__pthread_initial_thread) +#endif { /* Defined in ld.so. */ extern void *__libc_stack_end; @@ -448,6 +452,11 @@ int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr) attr->__stacksize = rl.rlim_cur; attr->__stackaddr = (void *) to; + /* The limit might be too high. This is a bogus + situation but try to avoid making it worse. */ + if ((size_t) attr->__stacksize > (size_t) attr->__stackaddr) + attr->__stacksize = (size_t) attr->__stackaddr; + /* We succeed and no need to look further. */ ret = 0; break; diff --git a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S index 8d3338afd0..23687342d1 100644 --- a/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S +++ b/linuxthreads/sysdeps/unix/sysv/linux/arm/vfork.S @@ -20,37 +20,60 @@ #include <sysdep-cancel.h> #define _ERRNO_H 1 #include <bits/errno.h> +#include <kernel-features.h> -/* Clone the calling process, but without copying the whole address -pace. +/* Clone the calling process, but without copying the whole address space. The calling process is suspended until the new process exits or is - replaced by a call to `execve'. Return -1 for errors, 0 to the new -rocess, + replaced by a call to `execve'. Return -1 for errors, 0 to the new process, and the process ID of the new process to the old process. */ PSEUDO_PROLOGUE ENTRY (__vfork) - SINGLE_THREAD_P - bne HIDDEN_JUMPTARGET (__fork) #ifdef __NR_vfork + +#ifdef SHARED + ldr ip, 1f + ldr r0, 2f +3: add ip, pc, ip + ldr r0, [ip, r0] +#else + ldr r0, 1f +#endif + movs r0, r0 + bne HIDDEN_JUMPTARGET (__fork) + swi __NR_vfork cmn a1, #4096 RETINSTR(movcc, pc, lr) +#ifndef __ASSUME_VFORK_SYSCALL /* Check if vfork syscall is known at all. */ - ldr a2, =-ENOSYS - teq a1, a2 + cmn a1, #ENOSYS bne PLTJMP(C_SYMBOL_NAME(__syscall_error)) #endif +#endif + +#ifndef __ASSUME_VFORK_SYSCALL /* If we don't have vfork, fork is close enough. */ swi __NR_fork cmn a1, #4096 RETINSTR(movcc, pc, lr) +#elif !defined __NR_vfork +# error "__NR_vfork not available and __ASSUME_VFORK_SYSCALL defined" +#endif b PLTJMP(C_SYMBOL_NAME(__syscall_error)) +#ifdef SHARED +1: .word _GLOBAL_OFFSET_TABLE_ - 3b - 8 +2: .word __libc_pthread_functions(GOTOFF) +#else + .weak pthread_create +1: .word pthread_create +#endif + PSEUDO_END (__vfork) libc_hidden_def (__vfork) |