am 5cf1f229: Merge "pthread_exit should call __NR_exit with status 0."

* commit '5cf1f229620d02c0ca266c9e03418fdeefd85191':
  pthread_exit should call __NR_exit with status 0.
This commit is contained in:
Elliott Hughes 2013-10-08 15:04:45 -07:00 committed by Android Git Automerger
commit 58b8f22566
6 changed files with 20 additions and 24 deletions

View file

@ -29,7 +29,7 @@
#include <machine/asm.h> #include <machine/asm.h>
#include <asm/unistd.h> #include <asm/unistd.h>
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) // void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
ENTRY(_exit_with_stack_teardown) ENTRY(_exit_with_stack_teardown)
mov lr, r2 mov lr, r2
ldr r7, =__NR_munmap ldr r7, =__NR_munmap

View file

@ -30,14 +30,14 @@
.text .text
/* void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode) */ // void _exit_with_stack_teardown(void * stackBase, int stackSize, int status)
.type _exit_with_stack_teardown, @function .type _exit_with_stack_teardown, @function
.global _exit_with_stack_teardown .global _exit_with_stack_teardown
.align 4 .align 4
.ent _exit_with_stack_teardown .ent _exit_with_stack_teardown
_exit_with_stack_teardown: _exit_with_stack_teardown:
move $s0,$a2 /* preserve retCode for exit() call */ move $s0,$a2 /* preserve status for exit() call */
li $v0,__NR_munmap li $v0,__NR_munmap
syscall /* the stack is destroyed by this call */ syscall /* the stack is destroyed by this call */

View file

@ -1,12 +1,12 @@
#include <asm/unistd.h> #include <asm/unistd.h>
#include <machine/asm.h> #include <machine/asm.h>
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) // void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
ENTRY(_exit_with_stack_teardown) ENTRY(_exit_with_stack_teardown)
// We can trash %ebx here since this call should never return. // We can trash %ebx here since this call should never return.
// We can also take advantage of the fact that the linux syscall trap // We can also take advantage of the fact that the linux syscall trap
// handler saves all the registers, so we don't need a stack to keep // handler saves all the registers, so we don't need a stack to keep
// the retCode argument for exit while doing the munmap */ // the status argument for exit while doing the munmap */
mov 4(%esp), %ebx // stackBase mov 4(%esp), %ebx // stackBase
mov 8(%esp), %ecx // stackSize mov 8(%esp), %ecx // stackSize
mov $__NR_munmap, %eax mov $__NR_munmap, %eax
@ -14,7 +14,7 @@ ENTRY(_exit_with_stack_teardown)
// If munmap failed, we ignore the failure and exit anyway. // If munmap failed, we ignore the failure and exit anyway.
mov %edx, %ebx // retCode mov %edx, %ebx // status
movl $__NR_exit, %eax movl $__NR_exit, %eax
int $0x80 int $0x80

View file

@ -29,17 +29,17 @@
#include <asm/unistd.h> #include <asm/unistd.h>
#include <machine/asm.h> #include <machine/asm.h>
// void _exit_with_stack_teardown(void* stackBase, int stackSize, int retCode) // void _exit_with_stack_teardown(void* stackBase, int stackSize, int status)
ENTRY(_exit_with_stack_teardown) ENTRY(_exit_with_stack_teardown)
// We take advantage of the fact that the linux syscall trap // We take advantage of the fact that the linux syscall trap
// handler saves all the registers, so we don't need to save // handler saves all the registers, so we don't need to save
// the retCode argument for exit(2) while doing the munmap(2). // the status argument for exit(2) while doing the munmap(2).
mov $__NR_munmap, %eax mov $__NR_munmap, %eax
syscall syscall
// If munmap failed, ignore the failure and exit anyway. // If munmap failed, ignore the failure and exit anyway.
mov %rdx, %rdi // retCode mov %rdx, %rdi // status
mov $__NR_exit, %eax mov $__NR_exit, %eax
syscall syscall

View file

@ -39,21 +39,17 @@ extern int __bionic_clone(unsigned long clone_flags,
int (*fn)(void *), int (*fn)(void *),
void *arg); void *arg);
extern void _exit_thread(int retCode); extern void _exit_thread(int status);
/* this function is called from the __bionic_clone /* this function is called from the __bionic_clone
* assembly fragment to call the thread function * assembly fragment to call the thread function
* then exit. */ * then exit. */
extern void extern void __bionic_clone_entry(int (*fn)(void*), void* arg) {
__bionic_clone_entry( int (*fn)(void *), void *arg ) int status = (*fn)(arg);
{ _exit_thread(status);
int ret = (*fn)(arg);
_exit_thread(ret);
} }
int int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) {
clone(int (*fn)(void *), void *child_stack, int flags, void* arg, ...)
{
va_list args; va_list args;
int *parent_tidptr = NULL; int *parent_tidptr = NULL;
void *new_tls = NULL; void *new_tls = NULL;

View file

@ -44,8 +44,8 @@
extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex); extern void pthread_debug_mutex_lock_check(pthread_mutex_t *mutex);
extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex); extern void pthread_debug_mutex_unlock_check(pthread_mutex_t *mutex);
extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode); extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int status);
extern void _exit_thread(int retCode); extern void _exit_thread(int status);
int __futex_wake_ex(volatile void *ftx, int pshared, int val) int __futex_wake_ex(volatile void *ftx, int pshared, int val)
{ {
@ -143,15 +143,15 @@ void pthread_exit(void * retval)
sigfillset(&mask); sigfillset(&mask);
sigdelset(&mask, SIGSEGV); sigdelset(&mask, SIGSEGV);
(void)sigprocmask(SIG_SETMASK, &mask, (sigset_t *)NULL); sigprocmask(SIG_SETMASK, &mask, NULL);
// destroy the thread stack
if (user_stack) { if (user_stack) {
_exit_thread((int)retval); // Cleaning up this thread's stack is the creator's responsibility, not ours.
_exit_thread(0);
} else { } else {
// We need to munmap the stack we're running on before calling exit. // We need to munmap the stack we're running on before calling exit.
// That's not something we can do in C. // That's not something we can do in C.
_exit_with_stack_teardown(stack_base, stack_size, (int)retval); _exit_with_stack_teardown(stack_base, stack_size, 0);
} }
} }