pthread_internal.h revision 6a7aaf46759db32c6ed0eb953a4a230dc96af0d9
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>
321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
338cf1b305670123aed7638d984ca39bfd22388440Yabin Cui#include "private/bionic_tls.h"
348cf1b305670123aed7638d984ca39bfd22388440Yabin Cui
3540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Has the thread been detached by a pthread_join or pthread_detach call? */
3640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes#define PTHREAD_ATTR_FLAG_DETACHED 0x00000001
3740a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes
3840a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Was the thread's stack allocated by the user rather than by us? */
3940a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes#define PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK 0x00000002
4040a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes
4140a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Has the thread been joined by another thread? */
4240a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes#define PTHREAD_ATTR_FLAG_JOINED 0x00000004
4340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes
4440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes/* Is this the main thread? */
4540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes#define PTHREAD_ATTR_FLAG_MAIN_THREAD 0x80000000
4640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes
47c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughesstruct pthread_internal_t {
48877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  struct pthread_internal_t* next;
49877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  struct pthread_internal_t* prev;
50877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
51877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pid_t tid;
52877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
537086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes private:
547086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t cached_pid_;
557086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
567086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes public:
577086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  pid_t invalidate_cached_pid() {
587086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    pid_t old_value;
597086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    get_cached_pid(&old_value);
607086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    set_cached_pid(0);
617086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    return old_value;
627086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
637086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
647086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  void set_cached_pid(pid_t value) {
657086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    cached_pid_ = value;
667086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
677086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
687086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  bool get_cached_pid(pid_t* cached_pid) {
697086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    *cached_pid = cached_pid_;
707086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes    return (*cached_pid != 0);
717086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes  }
727086ad6919feb2415c6027163f5c63323bcca27cElliott Hughes
7340a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes  bool user_allocated_stack() {
7440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes    return (attr.flags & PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK) != 0;
7540a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes  }
7640a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes
77877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  pthread_attr_t attr;
78877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
79877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  __pthread_cleanup_t* cleanup_stack;
80877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
81877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* (*start_routine)(void*);
82877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* start_routine_arg;
83877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* return_value;
84877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
85877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  void* alternate_signal_stack;
86877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes
87b30aff405a220495941f1673b0a5e66c4fa8b84cElliott Hughes  pthread_mutex_t startup_handshake_mutex;
88b30aff405a220495941f1673b0a5e66c4fa8b84cElliott Hughes
896a7aaf46759db32c6ed0eb953a4a230dc96af0d9Yabin Cui  /* Store real allocated stack size, including thread stack and pthread_internal_t. */
906a7aaf46759db32c6ed0eb953a4a230dc96af0d9Yabin Cui  int allocated_stack_size;
916a7aaf46759db32c6ed0eb953a4a230dc96af0d9Yabin Cui
928cf1b305670123aed7638d984ca39bfd22388440Yabin Cui  void* tls[BIONIC_TLS_SLOTS];
938cf1b305670123aed7638d984ca39bfd22388440Yabin Cui
94877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  /*
95877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   * The dynamic linker implements dlerror(3), which makes it hard for us to implement this
96877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   * per-thread buffer by simply using malloc(3) and free(3).
97877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes   */
985419b9474753d25dff947c7740532f86d130c0beElliott Hughes#define __BIONIC_DLERROR_BUFFER_SIZE 512
99877ec6d90418ff1d6597147d355a2229fdffae7eElliott Hughes  char dlerror_buffer[__BIONIC_DLERROR_BUFFER_SIZE];
1008cf1b305670123aed7638d984ca39bfd22388440Yabin Cui} __attribute__((aligned(16))); // Align it as thread stack top below it should be aligned.
1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
102cef3faec0ea40fdfe58e425fd0be64f00de6a26dElliott Hughes__LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread, bool add_to_thread_list);
103c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
10470b24b1cc2a1a4436b1fea3f8b76616fdcb27224Elliott Hughes__LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);
105c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ void _pthread_internal_add(pthread_internal_t* thread);
106a4831cb4a3f44b93788488db8ff9ea76613f0355Elliott Hughes
107a4831cb4a3f44b93788488db8ff9ea76613f0355Elliott Hughes/* Various third-party apps contain a backport of our pthread_rwlock implementation that uses this. */
108a4831cb4a3f44b93788488db8ff9ea76613f0355Elliott Hughesextern "C" __LIBC64_HIDDEN__ pthread_internal_t* __get_thread(void);
1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
11044b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes__LIBC_HIDDEN__ void pthread_key_clean_all(void);
1118cf1b305670123aed7638d984ca39bfd22388440Yabin Cui__LIBC_HIDDEN__ void _pthread_internal_remove_locked(pthread_internal_t* thread, bool free_thread);
11244b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes
11350af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom/*
11440a521744825b6060960c296d5fb3da4c6593d94Elliott Hughes * Traditionally we gave threads a 1MiB stack. When we started
11550af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * allocating per-thread alternate signal stacks to ease debugging of
11650af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * stack overflows, we subtracted the same amount we were using there
11750af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * from the default thread stack size. This should keep memory usage
11850af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom * roughly constant.
11950af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom */
12050af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom#define PTHREAD_STACK_SIZE_DEFAULT ((1 * 1024 * 1024) - SIGSTKSZ)
12150af69e8f326b2762a44d5fea2b118e7616e5d20Brian Carlstrom
1221728b2396591853345507a063ed6075dfd251706Elliott Hughes__LIBC_HIDDEN__ extern pthread_internal_t* g_thread_list;
1231728b2396591853345507a063ed6075dfd251706Elliott Hughes__LIBC_HIDDEN__ extern pthread_mutex_t g_thread_list_lock;
12444b53ad6818de344e0b499ad8fdbb21fcb0ff2b6Elliott Hughes
1254b558f50a42c97d461f1dede5aaaae490ea99e2eElliott Hughes/* Needed by fork. */
126c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
127c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
128c3f114037dbf028896310609fd28cf2b3da99c4dElliott Hughes__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent();
1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project
1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#endif /* _PTHREAD_INTERNAL_H_ */
131