pthread_internal.h revision 42d949ff9d2956e25f84e537f43a8f93ecb37baf
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
4342d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughesclass pthread_key_data_t {
4442d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughes public:
455e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui  uintptr_t seq; // Use uintptr_t just for alignment, as we use pointer below.
465e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui  void* data;
475e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui};
485e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui
4958cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cuienum ThreadJoinState {
5058cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui  THREAD_NOT_JOINED,
5158cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui  THREAD_EXITED_NOT_JOINED,
5258cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui  THREAD_JOINED,
5358cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui  THREAD_DETACHED
5458cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui};
5558cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui
5642d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughesclass thread_local_dtor;
57952e9eb0866bc2061b671e8d6c90cae275eda6bdYabin Cui
5842d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughesclass pthread_internal_t {
5942d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughes public:
6042d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughes  class pthread_internal_t* next;
6142d949ff9d2956e25f84e537f43a8f93ecb37bafElliott Hughes  class pthread_internal_t* prev;
62877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
63877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pid_t tid;
64877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
657086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes private:
667086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t cached_pid_;
677086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
687086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes public:
697086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t invalidate_cached_pid() {
707086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    pid_t old_value;
717086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    get_cached_pid(&old_value);
727086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    set_cached_pid(0);
737086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    return old_value;
747086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
757086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
767086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  void set_cached_pid(pid_t value) {
777086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    cached_pid_ = value;
787086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
797086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
807086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  bool get_cached_pid(pid_t* cached_pid) {
817086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    *cached_pid = cached_pid_;
827086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    return (*cached_pid != 0);
837086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
847086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
85877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_attr_t attr;
86877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
8758cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui  _Atomic(ThreadJoinState) join_state;
8858cf31b50699ed9f523de38c8e943f3bbd1ced9eYabin Cui
89877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  __pthread_cleanup_t* cleanup_stack;
90877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
91877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* (*start_routine)(void*);
92877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* start_routine_arg;
93877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* return_value;
94877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
95877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* alternate_signal_stack;
96877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
97d26e780df66b9add4cf7e7ebb2f6c6749d1c5050Yabin Cui  Lock startup_handshake_lock;
98b30aff405a220495941f1673b0a5e66c4fa8b84cElliott Hughes
99ba8dfc2669d658dc340eb8f9c9b40ca074f05047Yabin Cui  size_t mmap_size;
1006a7aaf46759db32c6ed0eb953a4a230dc96af0d9Yabin Cui
101952e9eb0866bc2061b671e8d6c90cae275eda6bdYabin Cui  thread_local_dtor* thread_local_dtors;
102952e9eb0866bc2061b671e8d6c90cae275eda6bdYabin Cui
1038cf1b305670123aed7638d984ca39bfd22388440Yabin Cui  void* tls[BIONIC_TLS_SLOTS];
1048cf1b305670123aed7638d984ca39bfd22388440Yabin Cui
1055e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui  pthread_key_data_t key_data[BIONIC_PTHREAD_KEY_COUNT];
1065e2bd719d7dd19afe55f8d4f24366c0230e0e6c7Yabin Cui
107877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  /*
108877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   * The dynamic linker implements dlerror(3), which makes it hard for us to implement this
109877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   * per-thread buffer by simply using malloc(3) and free(3).
110877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   */
1115419b9474753d25dff947c7740532f86d130c0beElliott Hughes#define __BIONIC_DLERROR_BUFFER_SIZE 512
112877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
113a2db50d5d7fa67b297eddd1c0549f08ea4b6a950Yabin Cui};
1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
115673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
116c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
11770b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes__LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);
118673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui
119673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ pthread_t           __pthread_internal_add(pthread_internal_t* thread);
120673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ pthread_internal_t* __pthread_internal_find(pthread_t pthread_id);
121673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ void                __pthread_internal_remove(pthread_internal_t* thread);
122673b15e4ee2c6d99b150aedddc0f389e29f98e1bYabin Cui__LIBC_HIDDEN__ void                __pthread_internal_remove_and_free(pthread_internal_t* thread);
123a4831cb4a3f44b93788488db8ff9ea76613f0355Elliott Hughes
1242f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui// Make __get_thread() inlined for performance reason. See http://b/19825434.
1252f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cuistatic inline __always_inline pthread_internal_t* __get_thread() {
1262f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui  return reinterpret_cast<pthread_internal_t*>(__get_tls()[TLS_SLOT_THREAD_ID]);
1272f836d4989845c0c82a1e4f99206fb0ff0d137a2Yabin Cui}
1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
12944b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes__LIBC_HIDDEN__ void pthread_key_clean_all(void);
13044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes
13150af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom/*
13240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes * Traditionally we gave threads a 1MiB stack. When we started
13350af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * allocating per-thread alternate signal stacks to ease debugging of
13450af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * stack overflows, we subtracted the same amount we were using there
13550af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * from the default thread stack size. This should keep memory usage
13650af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * roughly constant.
13750af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom */
13850af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ)
13950af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom
14033ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui// Leave room for a guard page in the internally created signal stacks.
14133ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#if defined(__LP64__)
14233ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui// SIGSTKSZ is not big enough for 64-bit arch. See http://b/23041777.
14333ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#define SIGNAL_STACK_SIZE (16 * 1024 + PAGE_SIZE)
14433ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#else
145ef115003012f61cf5539fdfeb201b98e4a92f610Yabin Cui#define SIGNAL_STACK_SIZE (SIGSTKSZ + PAGE_SIZE)
14633ac04a215a70d2f39f1ddec1bba5a42c0fd8beeYabin Cui#endif
147ef115003012f61cf5539fdfeb201b98e4a92f610Yabin Cui
1484b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes/* Needed by fork. */
149c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
150c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
151c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent();
1521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* _PTHREAD_INTERNAL_H_ */
154