pthread_internal.h revision d26e780df66b9add4cf7e7ebb2f6c6749d1c5050
11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the documentation and/or other materials provided with the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#ifndef _PTHREAD_INTERNAL_H_ 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#define _PTHREAD_INTERNAL_H_ 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <pthread.h> 3258cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui#include <stdatomic.h> 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 34d26e780df66b9add4cf7e7ebb2f6c6749d1c5050Yabin Cui#include "private/bionic_lock.h" 358cf1b305670123aed7638d984ca39bfd22388440Yabin Cui#include "private/bionic_tls.h" 368cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 3740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Has the thread been detached by a pthread_join or pthread_detach call? */ 3840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes#define PTHREAD_ATTR_FLAG_DETACHED 0x00000001 3940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 4040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Has the thread been joined by another thread? */ 41ba8dfc2669d658dc340eb8f9c9b40ca074f05047Yabin Cui#define PTHREAD_ATTR_FLAG_JOINED 0x00000002 4240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes 435e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cuistruct pthread_key_data_t { 445e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below. 455e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui void* data; 465e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui}; 475e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui 4858cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cuienum ThreadJoinState { 4958cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui THREAD_NOT_JOINED, 5058cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui THREAD_EXITED_NOT_JOINED, 5158cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui THREAD_JOINED, 5258cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui THREAD_DETACHED 5358cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui}; 5458cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui 55c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstruct pthread_internal_t { 56877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes struct pthread_internal_t* next; 57877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes struct pthread_internal_t* prev; 58877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 59877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pid_t tid; 60877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 617086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes private: 627086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t cached_pid_; 637086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 647086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes public: 657086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t invalidate_cached_pid() { 667086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes pid_t old_value; 677086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes get_cached_pid(&old_value); 687086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes set_cached_pid(0); 697086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes return old_value; 707086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes } 717086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 727086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes void set_cached_pid(pid_t value) { 737086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes cached_pid_ = value; 747086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes } 757086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 767086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes bool get_cached_pid(pid_t* cached_pid) { 777086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes *cached_pid = cached_pid_; 787086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes return (*cached_pid != 0); 797086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes } 807086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes 81877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes pthread_attr_t attr; 82877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 8358cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui _Atomic(ThreadJoinState) join_state; 8458cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui 85877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes __pthread_cleanup_t* cleanup_stack; 86877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 87877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes void* (*start_routine)(void*); 88877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes void* start_routine_arg; 89877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes void* return_value; 90877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 91877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes void* alternate_signal_stack; 92877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes 93d26e780df66b9add4cf7e7ebb2f6c6749d1c5050Yabin Cui Lock startup_handshake_lock; 94b30aff405a220495941f1673b0a5e66c4fa8b84cElliott Hughes 95ba8dfc2669d658dc340eb8f9c9b40ca074f05047Yabin Cui size_t mmap_size; 966a7aaf46759db32c6ed0eb953a4a230dc96af0d9Yabin Cui 978cf1b305670123aed7638d984ca39bfd22388440Yabin Cui void* tls[BIONIC_TLS_SLOTS]; 988cf1b305670123aed7638d984ca39bfd22388440Yabin Cui 995e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT]; 1005e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui 101877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes /* 102877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes * The dynamic linker implements dlerror(3), which makes it hard for us to implement this 103877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes * per-thread buffer by simply using malloc(3) and free(3). 104877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes */ 1055419b9474753d25dff947c7740532f86d130c0beElliott Hughes#define __BIONIC_DLERROR_BUFFER_SIZE 512 106877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE]; 107a2db50d5d7fa67b297eddd1c0549f08ea4b6a950Yabin Cui}; 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 109673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread); 110c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread); 11170b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes__LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*); 112673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui 113673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ pthread_t __pthread_internal_add(pthread_internal_t* thread); 114673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id); 115673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ void __pthread_internal_remove(pthread_internal_t* thread); 116673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ void __pthread_internal_remove_and_free(pthread_internal_t* thread); 117a4831cb4a3f44b93788488db8ff9ea76613f0355Elliott Hughes 1182f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui// Make __get_thread() inlined for performance reason. See http://b/19825434. 1192f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cuistatic inline __always_inline pthread_internal_t* __get_thread() { 1202f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui return reinterpret_cast<pthread_internal_t*>(__get_tls()[TLS_SLOT_THREAD_ID]); 1212f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui} 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 12344b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes__LIBC_HIDDEN__ void pthread_key_clean_all(void); 12444b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes 12550af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom/* 12640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes * Traditionally we gave threads a 1MiB stack. When we started 12750af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * allocating per-thread alternate signal stacks to ease debugging of 12850af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * stack overflows, we subtracted the same amount we were using there 12950af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * from the default thread stack size. This should keep memory usage 13050af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * roughly constant. 13150af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom */ 13250af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ) 13350af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom 13433ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui// Leave room for a guard page in the internally created signal stacks. 13533ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#if defined(__LP64__) 13633ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777. 13733ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE) 13833ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#else 139ef115003012f61cf5539fdfeb201b98e4a92f610Yabin Cui#define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE) 14033ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#endif 141ef115003012f61cf5539fdfeb201b98e4a92f610Yabin Cui 1424b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes/* Needed by fork. */ 143c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare(); 144c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_child(); 145c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent(); 1461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* _PTHREAD_INTERNAL_H_ */ 148