diff options
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/fork.cpp | 13 | ||||
-rw-r--r-- | libc/bionic/getpid.cpp | 47 | ||||
-rw-r--r-- | libc/bionic/jemalloc_wrapper.cpp (renamed from libc/bionic/jemalloc.cpp) | 16 | ||||
-rw-r--r-- | libc/bionic/libc_init_common.cpp | 17 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_check.cpp | 12 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_common.h | 7 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_leak.cpp | 14 | ||||
-rw-r--r-- | libc/bionic/malloc_debug_qemu.cpp | 10 | ||||
-rw-r--r-- | libc/bionic/pthread_create.cpp | 8 | ||||
-rw-r--r-- | libc/bionic/pthread_internal.h | 20 | ||||
-rw-r--r-- | libc/bionic/system_properties.cpp | 5 |
11 files changed, 126 insertions, 43 deletions
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/jemalloc.cpp b/libc/bionic/jemalloc_wrapper.cpp index 625d789e7..d1fe96056 100644 --- a/libc/bionic/jemalloc.cpp +++ b/libc/bionic/jemalloc_wrapper.cpp @@ -14,13 +14,19 @@ * limitations under the License. */ +#include <sys/param.h> #include <unistd.h> #include "jemalloc.h" +#include "private/bionic_macros.h" void* je_pvalloc(size_t bytes) { size_t pagesize = sysconf(_SC_PAGESIZE); - return je_memalign(pagesize, (bytes + pagesize - 1) & ~(pagesize - 1)); + size_t size = BIONIC_ALIGN(bytes, pagesize); + if (size < bytes) { + return NULL; + } + return je_memalign(pagesize, size); } #ifdef je_memalign @@ -31,11 +37,9 @@ void* je_pvalloc(size_t bytes) { // but this is not true. Both glibc and dlmalloc round up to the next power // of 2, so we'll do the same. void* je_memalign_round_up_boundary(size_t boundary, size_t size) { - unsigned int power_of_2 = static_cast<unsigned int>(boundary); - if (power_of_2 != 0) { - power_of_2 = 1UL << (sizeof(unsigned int)*8 - 1 - __builtin_clz(power_of_2)); - if (power_of_2 != boundary) { - boundary = power_of_2 << 1; + if (boundary != 0) { + if (!powerof2(boundary)) { + boundary = BIONIC_ROUND_UP_POWER_OF_2(boundary); } } else { boundary = 1; 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/malloc_debug_check.cpp b/libc/bionic/malloc_debug_check.cpp index faf61bf5c..e4e4c2eb0 100644 --- a/libc/bionic/malloc_debug_check.cpp +++ b/libc/bionic/malloc_debug_check.cpp @@ -38,6 +38,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/param.h> #include <sys/socket.h> #include <sys/system_properties.h> #include <sys/types.h> @@ -47,8 +48,9 @@ #include "debug_mapinfo.h" #include "debug_stacktrace.h" -#include "private/libc_logging.h" #include "malloc_debug_common.h" +#include "private/bionic_macros.h" +#include "private/libc_logging.h" #include "private/ScopedPthreadMutexLocker.h" #define MAX_BACKTRACE_DEPTH 16 @@ -350,8 +352,8 @@ extern "C" void* chk_memalign(size_t alignment, size_t bytes) { } // Make the alignment a power of two. - if (alignment & (alignment-1)) { - alignment = 1L << (31 - __builtin_clz(alignment)); + if (!powerof2(alignment)) { + alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment); } // here, alignment is at least MALLOC_ALIGNMENT<<1 bytes @@ -526,7 +528,7 @@ extern "C" struct mallinfo chk_mallinfo() { } extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) { - if ((alignment & (alignment - 1)) != 0) { + if (!powerof2(alignment)) { return EINVAL; } int saved_errno = errno; @@ -537,7 +539,7 @@ extern "C" int chk_posix_memalign(void** memptr, size_t alignment, size_t size) extern "C" void* chk_pvalloc(size_t bytes) { size_t pagesize = sysconf(_SC_PAGESIZE); - size_t size = (bytes + pagesize - 1) & ~(pagesize - 1); + size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; } diff --git a/libc/bionic/malloc_debug_common.h b/libc/bionic/malloc_debug_common.h index a0f9972dd..fb2f03d06 100644 --- a/libc/bionic/malloc_debug_common.h +++ b/libc/bionic/malloc_debug_common.h @@ -37,6 +37,7 @@ #include <stdint.h> #include <stdlib.h> +#include "private/bionic_config.h" #include "private/libc_logging.h" #define HASHTABLE_SIZE 1543 @@ -61,12 +62,6 @@ #define Malloc(function) dl ## function #endif -// valloc(3) and pvalloc(3) were removed from POSIX 2004. We do not include them -// for LP64, but the symbols remain in LP32 for binary compatibility. -#ifndef __LP64__ -#define HAVE_DEPRECATED_MALLOC_FUNCS 1 -#endif - // ============================================================================= // Structures // ============================================================================= diff --git a/libc/bionic/malloc_debug_leak.cpp b/libc/bionic/malloc_debug_leak.cpp index 2cc38ccf5..308d40b9a 100644 --- a/libc/bionic/malloc_debug_leak.cpp +++ b/libc/bionic/malloc_debug_leak.cpp @@ -37,6 +37,7 @@ #include <stdio.h> #include <stdlib.h> #include <string.h> +#include <sys/param.h> #include <sys/select.h> #include <sys/socket.h> #include <sys/system_properties.h> @@ -48,6 +49,7 @@ #include "debug_stacktrace.h" #include "malloc_debug_common.h" +#include "private/bionic_macros.h" #include "private/libc_logging.h" #include "private/ScopedPthreadMutexLocker.h" @@ -255,7 +257,7 @@ extern "C" struct mallinfo fill_mallinfo() { } extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) { - if ((alignment & (alignment - 1)) != 0) { + if (!powerof2(alignment)) { return EINVAL; } int saved_errno = errno; @@ -266,7 +268,7 @@ extern "C" int fill_posix_memalign(void** memptr, size_t alignment, size_t size) extern "C" void* fill_pvalloc(size_t bytes) { size_t pagesize = sysconf(_SC_PAGESIZE); - size_t size = (bytes + pagesize - 1) & ~(pagesize - 1); + size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; } @@ -401,8 +403,8 @@ extern "C" void* leak_memalign(size_t alignment, size_t bytes) { } // need to make sure it's a power of two - if (alignment & (alignment-1)) { - alignment = 1L << (31 - __builtin_clz(alignment)); + if (!powerof2(alignment)) { + alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment); } // here, alignment is at least MALLOC_ALIGNMENT<<1 bytes @@ -464,7 +466,7 @@ extern "C" struct mallinfo leak_mallinfo() { } extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) { - if ((alignment & (alignment - 1)) != 0) { + if (!powerof2(alignment)) { return EINVAL; } int saved_errno = errno; @@ -475,7 +477,7 @@ extern "C" int leak_posix_memalign(void** memptr, size_t alignment, size_t size) extern "C" void* leak_pvalloc(size_t bytes) { size_t pagesize = sysconf(_SC_PAGESIZE); - size_t size = (bytes + pagesize - 1) & ~(pagesize - 1); + size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow return NULL; } diff --git a/libc/bionic/malloc_debug_qemu.cpp b/libc/bionic/malloc_debug_qemu.cpp index 9b3bb5578..fd5161a7e 100644 --- a/libc/bionic/malloc_debug_qemu.cpp +++ b/libc/bionic/malloc_debug_qemu.cpp @@ -47,11 +47,13 @@ #include <stdio.h> #include <fcntl.h> #include <sys/mman.h> +#include <sys/param.h> #include <pthread.h> #include <unistd.h> #include <errno.h> -#include "private/libc_logging.h" #include "malloc_debug_common.h" +#include "private/bionic_macros.h" +#include "private/libc_logging.h" /* This file should be included into the build only when * MALLOC_QEMU_INSTRUMENT macro is defined. */ @@ -970,8 +972,8 @@ extern "C" void* qemu_instrumented_memalign(size_t alignment, size_t bytes) { // size. if (alignment < DEFAULT_PREFIX_SIZE) { alignment = DEFAULT_PREFIX_SIZE; - } else if (alignment & (alignment - 1)) { - alignment = 1L << (31 - __builtin_clz(alignment)); + } else if (!powerof2(alignment)) { + alignment = BIONIC_ROUND_UP_POWER_OF_2(alignment); } desc.prefix_size = alignment; desc.requested_bytes = bytes; @@ -1047,7 +1049,7 @@ extern "C" int qemu_instrumented_posix_memalign(void** memptr, size_t alignment, extern "C" void* qemu_instrumented_pvalloc(size_t bytes) { size_t pagesize = sysconf(_SC_PAGESIZE); - size_t size = (bytes + pagesize - 1) & ~(pagesize - 1); + size_t size = BIONIC_ALIGN(bytes, pagesize); if (size < bytes) { // Overflow qemu_error_log("<libc_pid=%03u, pid=%03u> pvalloc(%zu): overflow (%zu).", malloc_pid, getpid(), bytes, size); diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp index c4cb262ac..2ded22b0f 100644 --- a/libc/bionic/pthread_create.cpp +++ b/libc/bionic/pthread_create.cpp @@ -30,9 +30,11 @@ #include <errno.h> #include <sys/mman.h> +#include <unistd.h> #include "pthread_internal.h" +#include "private/bionic_macros.h" #include "private/bionic_ssp.h" #include "private/bionic_tls.h" #include "private/libc_logging.h" @@ -183,8 +185,8 @@ int pthread_create(pthread_t* thread_out, pthread_attr_t const* attr, } // Make sure the stack size and guard size are multiples of PAGE_SIZE. - thread->attr.stack_size = (thread->attr.stack_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); - thread->attr.guard_size = (thread->attr.guard_size + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); + thread->attr.stack_size = BIONIC_ALIGN(thread->attr.stack_size, PAGE_SIZE); + thread->attr.guard_size = BIONIC_ALIGN(thread->attr.guard_size, PAGE_SIZE); if (thread->attr.stack_base == NULL) { // The caller didn't provide a stack, so allocate one. @@ -219,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; diff --git a/libc/bionic/system_properties.cpp b/libc/bionic/system_properties.cpp index 761858617..a564c3939 100644 --- a/libc/bionic/system_properties.cpp +++ b/libc/bionic/system_properties.cpp @@ -55,9 +55,6 @@ #include "private/bionic_futex.h" #include "private/bionic_macros.h" -#define ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1)) - - static const char property_service_socket[] = "/dev/socket/" PROP_SERVICE_NAME; @@ -301,7 +298,7 @@ static int map_prop_area() static void *allocate_obj(const size_t size, uint32_t *const off) { prop_area *pa = __system_property_area__; - const size_t aligned = ALIGN(size, sizeof(uint32_t)); + const size_t aligned = BIONIC_ALIGN(size, sizeof(uint32_t)); if (pa->bytes_used + aligned > pa_data_size) { return NULL; } |