diff options
author | Elliott Hughes <enh@google.com> | 2014-06-20 18:47:46 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2014-06-20 00:26:25 +0000 |
commit | fb0a3622f79bb0a31dd4d0e2f9cea990075ef129 (patch) | |
tree | 06b343d028a4ade5878deb2d0d1b915a0fc8f0a1 /libc | |
parent | e58055f05dbbb22a9e308c4b628b93d858f57685 (diff) | |
parent | 7086ad6919feb2415c6027163f5c63323bcca27c (diff) | |
download | android_bionic-fb0a3622f79bb0a31dd4d0e2f9cea990075ef129.tar.gz android_bionic-fb0a3622f79bb0a31dd4d0e2f9cea990075ef129.tar.bz2 android_bionic-fb0a3622f79bb0a31dd4d0e2f9cea990075ef129.zip |
Merge "Cache getpid."
Diffstat (limited to 'libc')
-rw-r--r-- | libc/Android.mk | 1 | ||||
-rw-r--r-- | libc/SYSCALLS.TXT | 2 | ||||
-rw-r--r-- | libc/arch-arm/syscalls/__getpid.S (renamed from libc/arch-arm/syscalls/getpid.S) | 4 | ||||
-rw-r--r-- | libc/arch-arm64/syscalls/__getpid.S (renamed from libc/arch-arm64/syscalls/getpid.S) | 5 | ||||
-rw-r--r-- | libc/arch-mips/syscalls/__getpid.S (renamed from libc/arch-mips/syscalls/getpid.S) | 4 | ||||
-rw-r--r-- | libc/arch-mips64/syscalls/__getpid.S (renamed from libc/arch-mips64/syscalls/getpid.S) | 5 | ||||
-rw-r--r-- | libc/arch-x86/syscalls/__getpid.S (renamed from libc/arch-x86/syscalls/getpid.S) | 4 | ||||
-rw-r--r-- | libc/arch-x86_64/syscalls/__getpid.S (renamed from libc/arch-x86_64/syscalls/getpid.S) | 5 | ||||
-rw-r--r-- | libc/bionic/fork.cpp | 13 | ||||
-rw-r--r-- | libc/bionic/getpid.cpp | 47 | ||||
-rw-r--r-- | libc/bionic/libc_init_common.cpp | 17 | ||||
-rw-r--r-- | libc/bionic/pthread_create.cpp | 3 | ||||
-rw-r--r-- | libc/bionic/pthread_internal.h | 20 |
13 files changed, 107 insertions, 23 deletions
diff --git a/libc/Android.mk b/libc/Android.mk index a6298a0ad..002978c4e 100644 --- a/libc/Android.mk +++ b/libc/Android.mk @@ -127,6 +127,7 @@ libc_bionic_src_files := \ bionic/getauxval.cpp \ bionic/getcwd.cpp \ bionic/getpgrp.cpp \ + bionic/getpid.cpp \ bionic/gettid.cpp \ bionic/inotify_init.cpp \ bionic/lchown.cpp \ diff --git a/libc/SYSCALLS.TXT b/libc/SYSCALLS.TXT index 369b23c76..839cfb7f4 100644 --- a/libc/SYSCALLS.TXT +++ b/libc/SYSCALLS.TXT @@ -97,7 +97,7 @@ ssize_t pread64|pread(int, void*, size_t, off_t) arm64,mips64,x86_64 ssize_t pwrite64(int, void*, size_t, off64_t) arm,mips,x86 ssize_t pwrite64|pwrite(int, void*, size_t, off_t) arm64,mips64,x86_64 int close(int) all -pid_t getpid() all +pid_t __getpid:getpid() all int munmap(void*, size_t) all void* mremap(void*, size_t, size_t, unsigned long) all int msync(const void*, size_t, int) all diff --git a/libc/arch-arm/syscalls/getpid.S b/libc/arch-arm/syscalls/__getpid.S index 10bcb8e28..eedc33a5f 100644 --- a/libc/arch-arm/syscalls/getpid.S +++ b/libc/arch-arm/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) mov ip, r7 ldr r7, =__NR_getpid swi #0 @@ -11,4 +11,4 @@ ENTRY(getpid) bxls lr neg r0, r0 b __set_errno -END(getpid) +END(__getpid) diff --git a/libc/arch-arm64/syscalls/getpid.S b/libc/arch-arm64/syscalls/__getpid.S index 1802ce80a..c3003c302 100644 --- a/libc/arch-arm64/syscalls/getpid.S +++ b/libc/arch-arm64/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) mov x8, __NR_getpid svc #0 @@ -11,4 +11,5 @@ ENTRY(getpid) b.hi __set_errno ret -END(getpid) +END(__getpid) +.hidden __getpid diff --git a/libc/arch-mips/syscalls/getpid.S b/libc/arch-mips/syscalls/__getpid.S index a053f5be0..52cf6f426 100644 --- a/libc/arch-mips/syscalls/getpid.S +++ b/libc/arch-mips/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) .set noreorder .cpload t9 li v0, __NR_getpid @@ -16,4 +16,4 @@ ENTRY(getpid) j t9 nop .set reorder -END(getpid) +END(__getpid) diff --git a/libc/arch-mips64/syscalls/getpid.S b/libc/arch-mips64/syscalls/__getpid.S index 3b457b532..0977ff023 100644 --- a/libc/arch-mips64/syscalls/getpid.S +++ b/libc/arch-mips64/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) .set push .set noreorder li v0, __NR_getpid @@ -22,4 +22,5 @@ ENTRY(getpid) j t9 move ra, t0 .set pop -END(getpid) +END(__getpid) +.hidden __getpid diff --git a/libc/arch-x86/syscalls/getpid.S b/libc/arch-x86/syscalls/__getpid.S index 0e12d5a3e..f138d2f88 100644 --- a/libc/arch-x86/syscalls/getpid.S +++ b/libc/arch-x86/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) movl $__NR_getpid, %eax int $0x80 cmpl $-MAX_ERRNO, %eax @@ -13,4 +13,4 @@ ENTRY(getpid) addl $4, %esp 1: ret -END(getpid) +END(__getpid) diff --git a/libc/arch-x86_64/syscalls/getpid.S b/libc/arch-x86_64/syscalls/__getpid.S index a2d732c9e..bd1bf1ee1 100644 --- a/libc/arch-x86_64/syscalls/getpid.S +++ b/libc/arch-x86_64/syscalls/__getpid.S @@ -2,7 +2,7 @@ #include <private/bionic_asm.h> -ENTRY(getpid) +ENTRY(__getpid) movl $__NR_getpid, %eax syscall cmpq $-MAX_ERRNO, %rax @@ -12,4 +12,5 @@ ENTRY(getpid) call __set_errno 1: ret -END(getpid) +END(__getpid) +.hidden __getpid diff --git a/libc/bionic/fork.cpp b/libc/bionic/fork.cpp index a0f98e42f..6cfc73664 100644 --- a/libc/bionic/fork.cpp +++ b/libc/bionic/fork.cpp @@ -31,19 +31,26 @@ #include "pthread_internal.h" +#define FORK_FLAGS (CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD) + int fork() { __bionic_atfork_run_prepare(); pthread_internal_t* self = __get_thread(); - int flags = CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD; + + // Remember the parent pid and invalidate the cached value while we fork. + pid_t parent_pid = self->invalidate_cached_pid(); + #if defined(__x86_64__) // sys_clone's last two arguments are flipped on x86-64. - int result = syscall(__NR_clone, flags, NULL, NULL, &(self->tid), NULL); + int result = syscall(__NR_clone, FORK_FLAGS, NULL, NULL, &(self->tid), NULL); #else - int result = syscall(__NR_clone, flags, NULL, NULL, NULL, &(self->tid)); + int result = syscall(__NR_clone, FORK_FLAGS, NULL, NULL, NULL, &(self->tid)); #endif if (result == 0) { + self->set_cached_pid(gettid()); __bionic_atfork_run_child(); } else { + self->set_cached_pid(parent_pid); __bionic_atfork_run_parent(); } return result; diff --git a/libc/bionic/getpid.cpp b/libc/bionic/getpid.cpp new file mode 100644 index 000000000..a3d5b35c9 --- /dev/null +++ b/libc/bionic/getpid.cpp @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 The Android Open Source Project + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT + * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <unistd.h> + +#include "pthread_internal.h" + +extern "C" pid_t __getpid(); + +pid_t getpid() { + pthread_internal_t* self = __get_thread(); + + // Do we have a valid cached pid? + pid_t cached_pid; + if (__predict_true(self->get_cached_pid(&cached_pid))) { + return cached_pid; + } + + // We're still in the dynamic linker or we're in the middle of forking, so ask the kernel. + // We don't know whether it's safe to update the cached value, so don't try. + return __getpid(); +} diff --git a/libc/bionic/libc_init_common.cpp b/libc/bionic/libc_init_common.cpp index abf2d3674..fa61c3c10 100644 --- a/libc/bionic/libc_init_common.cpp +++ b/libc/bionic/libc_init_common.cpp @@ -86,21 +86,24 @@ static size_t get_main_thread_stack_size() { void __libc_init_tls(KernelArgumentBlock& args) { __libc_auxv = args.auxv; - uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; - size_t stack_size = get_main_thread_stack_size(); - uintptr_t stack_bottom = stack_top - stack_size; - static void* tls[BIONIC_TLS_SLOTS]; static pthread_internal_t main_thread; main_thread.tls = tls; // Tell the kernel to clear our tid field when we exit, so we're like any other pthread. + // As a side-effect, this tells us our pid (which is the same as the main thread's tid). main_thread.tid = __set_tid_address(&main_thread.tid); + main_thread.set_cached_pid(main_thread.tid); + + // Work out the extent of the main thread's stack. + uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE; + size_t stack_size = get_main_thread_stack_size(); + void* stack_bottom = reinterpret_cast<void*>(stack_top - stack_size); - // We already have a stack, and we don't want to free it up on exit (because things like - // environment variables with global scope live on it). + // We don't want to free the main thread's stack even when the main thread exits + // because things like environment variables with global scope live on it. pthread_attr_init(&main_thread.attr); - pthread_attr_setstack(&main_thread.attr, (void*) stack_bottom, stack_size); + pthread_attr_setstack(&main_thread.attr, stack_bottom, stack_size); main_thread.attr.flags = PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK | PTHREAD_ATTR_FLAG_MAIN_THREAD; __init_thread(&main_thread, false); diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index c83b5a0ee..2ded22b0f 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -30,6 +30,7 @@ #include <errno.h> #include <sys/mman.h> +#include <unistd.h> #include "pthread_internal.h" @@ -220,6 +221,8 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, thread->start_routine = start_routine; thread->start_routine_arg = arg; + thread->set_cached_pid(getpid()); + int flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM | CLONE_SETTLS | CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID; void* tls = thread->tls; diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h index 490ae86d4..e05d15c79 100644 --- a/libc/bionic/pthread_internal.h +++ b/libc/bionic/pthread_internal.h @@ -36,6 +36,26 @@ struct pthread_internal_t { pid_t tid; + private: + pid_t cached_pid_; + + public: + pid_t invalidate_cached_pid() { + pid_t old_value; + get_cached_pid(&old_value); + set_cached_pid(0); + return old_value; + } + + void set_cached_pid(pid_t value) { + cached_pid_ = value; + } + + bool get_cached_pid(pid_t* cached_pid) { + *cached_pid = cached_pid_; + return (*cached_pid != 0); + } + void** tls; pthread_attr_t attr; |