Clean up forking and cloning.
The kernel now maintains the pthread_internal_t::tid field for us, and __clone was only used in one place so let's inline it so we don't have to leave such a dangerous function lying around. Also rename files to match their content and remove some useless #includes. Change-Id: I24299fb4a940e394de75f864ee36fdabbd9438f9
This commit is contained in:
		@@ -77,7 +77,6 @@ libc_common_src_files := \
 | 
			
		||||
	bionic/atol.c \
 | 
			
		||||
	bionic/atoll.c \
 | 
			
		||||
	bionic/bindresvport.c \
 | 
			
		||||
	bionic/bionic_clone.c \
 | 
			
		||||
	bionic/clearenv.c \
 | 
			
		||||
	bionic/daemon.c \
 | 
			
		||||
	bionic/err.c \
 | 
			
		||||
@@ -207,6 +206,7 @@ libc_bionic_src_files := \
 | 
			
		||||
    bionic/brk.cpp \
 | 
			
		||||
    bionic/chmod.cpp \
 | 
			
		||||
    bionic/chown.cpp \
 | 
			
		||||
    bionic/clone.cpp \
 | 
			
		||||
    bionic/dirent.cpp \
 | 
			
		||||
    bionic/dup2.cpp \
 | 
			
		||||
    bionic/epoll_create.cpp \
 | 
			
		||||
 
 | 
			
		||||
@@ -275,9 +275,6 @@ int     sysinfo(struct sysinfo*)  all
 | 
			
		||||
int     personality(unsigned long)  all
 | 
			
		||||
long    perf_event_open(struct perf_event_attr* attr_uptr, pid_t pid, int cpu, int group_fd, unsigned long flags) all
 | 
			
		||||
 | 
			
		||||
pid_t __clone:clone(int, void*, int*, void*, int*)  all
 | 
			
		||||
int __set_tid_address:set_tid_address(int*) all
 | 
			
		||||
 | 
			
		||||
int epoll_create1(int)  all
 | 
			
		||||
int epoll_ctl(int, int op, int, struct epoll_event*)  all
 | 
			
		||||
int __epoll_pwait:epoll_pwait(int, struct epoll_event*, int, int, const sigset_t*, size_t)  all
 | 
			
		||||
@@ -296,6 +293,8 @@ int inotify_rm_watch(int, unsigned int)  all
 | 
			
		||||
int __pselect6:pselect6(int, fd_set*, fd_set*, fd_set*, timespec*, void*)  all
 | 
			
		||||
int __ppoll:ppoll(pollfd*, unsigned int, timespec*, const sigset_t*, size_t)  all
 | 
			
		||||
 | 
			
		||||
int __set_tid_address:set_tid_address(int*)  all
 | 
			
		||||
 | 
			
		||||
pid_t wait4(pid_t, int*, int, struct rusage*)  all
 | 
			
		||||
int __waitid:waitid(int, pid_t, struct siginfo_t*, int, void*)  all
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
# Generated by gensyscalls.py. Do not edit.
 | 
			
		||||
syscall_src :=
 | 
			
		||||
syscall_src += arch-aarch64/syscalls/__brk.S
 | 
			
		||||
syscall_src += arch-aarch64/syscalls/__clone.S
 | 
			
		||||
syscall_src += arch-aarch64/syscalls/__epoll_pwait.S
 | 
			
		||||
syscall_src += arch-aarch64/syscalls/__exit.S
 | 
			
		||||
syscall_src += arch-aarch64/syscalls/__getcpu.S
 | 
			
		||||
 
 | 
			
		||||
@@ -1,22 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clone)
 | 
			
		||||
    stp     x29, x30, [sp, #-16]!
 | 
			
		||||
    mov     x29,  sp
 | 
			
		||||
    str     x8,       [sp, #-16]!
 | 
			
		||||
 | 
			
		||||
    mov     x8, __NR_clone
 | 
			
		||||
    svc     #0
 | 
			
		||||
 | 
			
		||||
    ldr     x8,       [sp], #16
 | 
			
		||||
    ldp     x29, x30, [sp], #16
 | 
			
		||||
 | 
			
		||||
    cmn     x0, #(MAX_ERRNO + 1)
 | 
			
		||||
    cneg    x0, x0, hi
 | 
			
		||||
    b.hi    __set_errno
 | 
			
		||||
 | 
			
		||||
    ret
 | 
			
		||||
END(__clone)
 | 
			
		||||
.hidden _C_LABEL(__clone)
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
_LIBC_ARCH_COMMON_SRC_FILES := \
 | 
			
		||||
    arch-arm/bionic/abort_arm.S \
 | 
			
		||||
    arch-arm/bionic/atomics_arm.c \
 | 
			
		||||
    arch-arm/bionic/clone.S \
 | 
			
		||||
    arch-arm/bionic/__bionic_clone.S \
 | 
			
		||||
    arch-arm/bionic/eabi.c \
 | 
			
		||||
    arch-arm/bionic/_exit_with_stack_teardown.S \
 | 
			
		||||
    arch-arm/bionic/futex_arm.S \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
# Generated by gensyscalls.py. Do not edit.
 | 
			
		||||
syscall_src :=
 | 
			
		||||
syscall_src += arch-arm/syscalls/__brk.S
 | 
			
		||||
syscall_src += arch-arm/syscalls/__clone.S
 | 
			
		||||
syscall_src += arch-arm/syscalls/__epoll_pwait.S
 | 
			
		||||
syscall_src += arch-arm/syscalls/__exit.S
 | 
			
		||||
syscall_src += arch-arm/syscalls/__fcntl64.S
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clone)
 | 
			
		||||
    mov     ip, sp
 | 
			
		||||
    .save   {r4, r5, r6, r7}
 | 
			
		||||
    stmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    ldmfd   ip, {r4, r5, r6}
 | 
			
		||||
    ldr     r7, =__NR_clone
 | 
			
		||||
    swi     #0
 | 
			
		||||
    ldmfd   sp!, {r4, r5, r6, r7}
 | 
			
		||||
    cmn     r0, #(MAX_ERRNO + 1)
 | 
			
		||||
    bxls    lr
 | 
			
		||||
    neg     r0, r0
 | 
			
		||||
    b       __set_errno
 | 
			
		||||
END(__clone)
 | 
			
		||||
@@ -1,7 +1,7 @@
 | 
			
		||||
_LIBC_ARCH_COMMON_SRC_FILES := \
 | 
			
		||||
    arch-mips/bionic/__bionic_clone.S \
 | 
			
		||||
    arch-mips/bionic/bzero.S \
 | 
			
		||||
    arch-mips/bionic/cacheflush.cpp \
 | 
			
		||||
    arch-mips/bionic/clone.S \
 | 
			
		||||
    arch-mips/bionic/_exit_with_stack_teardown.S \
 | 
			
		||||
    arch-mips/bionic/futex_mips.S \
 | 
			
		||||
    arch-mips/bionic/__get_sp.S \
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
# Generated by gensyscalls.py. Do not edit.
 | 
			
		||||
syscall_src :=
 | 
			
		||||
syscall_src += arch-mips/syscalls/__brk.S
 | 
			
		||||
syscall_src += arch-mips/syscalls/__clone.S
 | 
			
		||||
syscall_src += arch-mips/syscalls/__epoll_pwait.S
 | 
			
		||||
syscall_src += arch-mips/syscalls/__exit.S
 | 
			
		||||
syscall_src += arch-mips/syscalls/__fcntl64.S
 | 
			
		||||
 
 | 
			
		||||
@@ -1,23 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <asm/unistd.h>
 | 
			
		||||
    .text
 | 
			
		||||
    .globl __clone
 | 
			
		||||
    .align 4
 | 
			
		||||
    .ent __clone
 | 
			
		||||
 | 
			
		||||
__clone:
 | 
			
		||||
    .set noreorder
 | 
			
		||||
    .cpload $t9
 | 
			
		||||
    li $v0, __NR_clone
 | 
			
		||||
    syscall
 | 
			
		||||
    bnez $a3, 1f
 | 
			
		||||
    move $a0, $v0
 | 
			
		||||
    j $ra
 | 
			
		||||
    nop
 | 
			
		||||
1:
 | 
			
		||||
    la $t9,__set_errno
 | 
			
		||||
    j $t9
 | 
			
		||||
    nop
 | 
			
		||||
    .set reorder
 | 
			
		||||
    .end __clone
 | 
			
		||||
@@ -1,7 +1,6 @@
 | 
			
		||||
# Generated by gensyscalls.py. Do not edit.
 | 
			
		||||
syscall_src :=
 | 
			
		||||
syscall_src += arch-x86/syscalls/__brk.S
 | 
			
		||||
syscall_src += arch-x86/syscalls/__clone.S
 | 
			
		||||
syscall_src += arch-x86/syscalls/__epoll_pwait.S
 | 
			
		||||
syscall_src += arch-x86/syscalls/__exit.S
 | 
			
		||||
syscall_src += arch-x86/syscalls/__fcntl64.S
 | 
			
		||||
 
 | 
			
		||||
@@ -1,32 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clone)
 | 
			
		||||
    pushl   %ebx
 | 
			
		||||
    pushl   %ecx
 | 
			
		||||
    pushl   %edx
 | 
			
		||||
    pushl   %esi
 | 
			
		||||
    pushl   %edi
 | 
			
		||||
    mov     24(%esp), %ebx
 | 
			
		||||
    mov     28(%esp), %ecx
 | 
			
		||||
    mov     32(%esp), %edx
 | 
			
		||||
    mov     36(%esp), %esi
 | 
			
		||||
    mov     40(%esp), %edi
 | 
			
		||||
    movl    $__NR_clone, %eax
 | 
			
		||||
    int     $0x80
 | 
			
		||||
    cmpl    $-MAX_ERRNO, %eax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    pushl   %eax
 | 
			
		||||
    call    __set_errno
 | 
			
		||||
    addl    $4, %esp
 | 
			
		||||
    orl     $-1, %eax
 | 
			
		||||
1:
 | 
			
		||||
    popl    %edi
 | 
			
		||||
    popl    %esi
 | 
			
		||||
    popl    %edx
 | 
			
		||||
    popl    %ecx
 | 
			
		||||
    popl    %ebx
 | 
			
		||||
    ret
 | 
			
		||||
END(__clone)
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
_LIBC_ARCH_COMMON_SRC_FILES := \
 | 
			
		||||
    arch-x86/bionic/clone.S \
 | 
			
		||||
    arch-x86/bionic/__bionic_clone.S \
 | 
			
		||||
    arch-x86/bionic/_exit_with_stack_teardown.S \
 | 
			
		||||
    arch-x86/bionic/futex_x86.S \
 | 
			
		||||
    arch-x86/bionic/__get_sp.S \
 | 
			
		||||
 
 | 
			
		||||
@@ -40,8 +40,13 @@ ENTRY(__bionic_clone)
 | 
			
		||||
        movq    %rax, -8(%rsi)  # Write 'arg'.
 | 
			
		||||
 | 
			
		||||
        subq    $16, %rsi
 | 
			
		||||
 | 
			
		||||
        # Translate to the kernel calling convention and swap the 'tls' and 'child_tid' arguments.
 | 
			
		||||
        # They're flipped for x86-64 compared to all our other architectures and __bionic_clone.
 | 
			
		||||
        movq    %r8, %r10
 | 
			
		||||
        movq    %rcx, %r8
 | 
			
		||||
 | 
			
		||||
        # Make the system call.
 | 
			
		||||
        movl    $__NR_clone, %eax
 | 
			
		||||
        syscall
 | 
			
		||||
        testl   %eax, %eax
 | 
			
		||||
@@ -2,7 +2,6 @@
 | 
			
		||||
syscall_src :=
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__arch_prctl.S
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__brk.S
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__clone.S
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__epoll_pwait.S
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__exit.S
 | 
			
		||||
syscall_src += arch-x86_64/syscalls/__getcpu.S
 | 
			
		||||
 
 | 
			
		||||
@@ -1,18 +0,0 @@
 | 
			
		||||
/* Generated by gensyscalls.py. Do not edit. */
 | 
			
		||||
 | 
			
		||||
#include <private/bionic_asm.h>
 | 
			
		||||
 | 
			
		||||
ENTRY(__clone)
 | 
			
		||||
    movq    %rcx, %r10
 | 
			
		||||
    movl    $__NR_clone, %eax
 | 
			
		||||
    syscall
 | 
			
		||||
    cmpq    $-MAX_ERRNO, %rax
 | 
			
		||||
    jb      1f
 | 
			
		||||
    negl    %eax
 | 
			
		||||
    movl    %eax, %edi
 | 
			
		||||
    call    __set_errno
 | 
			
		||||
    orq     $-1, %rax
 | 
			
		||||
1:
 | 
			
		||||
    ret
 | 
			
		||||
END(__clone)
 | 
			
		||||
.hidden _C_LABEL(__clone)
 | 
			
		||||
@@ -1,5 +1,5 @@
 | 
			
		||||
_LIBC_ARCH_COMMON_SRC_FILES := \
 | 
			
		||||
    arch-x86_64/bionic/clone.S \
 | 
			
		||||
    arch-x86_64/bionic/__bionic_clone.S \
 | 
			
		||||
    arch-x86_64/bionic/_exit_with_stack_teardown.S \
 | 
			
		||||
    arch-x86_64/bionic/futex_x86_64.S \
 | 
			
		||||
    arch-x86_64/bionic/__get_sp.S \
 | 
			
		||||
 
 | 
			
		||||
@@ -25,41 +25,39 @@
 | 
			
		||||
 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 | 
			
		||||
 * SUCH DAMAGE.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#define __GNU_SOURCE 1
 | 
			
		||||
#include <sched.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdarg.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
extern pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg);
 | 
			
		||||
extern void __exit(int status);
 | 
			
		||||
extern "C" pid_t __bionic_clone(uint32_t flags, void* child_stack, int* parent_tid, void* tls, int* child_tid, int (*fn)(void*), void* arg);
 | 
			
		||||
extern "C" void __exit(int status);
 | 
			
		||||
 | 
			
		||||
/* this function is called from the __bionic_clone
 | 
			
		||||
 * assembly fragment to call the thread function
 | 
			
		||||
 * then exit. */
 | 
			
		||||
extern void __bionic_clone_entry(int (*fn)(void*), void* arg) {
 | 
			
		||||
// Called from the __bionic_clone assembler to call the thread function then exit.
 | 
			
		||||
extern "C" void __bionic_clone_entry(int (*fn)(void*), void* arg) {
 | 
			
		||||
  int status = (*fn)(arg);
 | 
			
		||||
  __exit(status);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int clone(int (*fn)(void*), void* child_stack, int flags, void* arg, ...) {
 | 
			
		||||
    va_list  args;
 | 
			
		||||
    int     *parent_tidptr = NULL;
 | 
			
		||||
    void    *new_tls = NULL;
 | 
			
		||||
    int     *child_tidptr = NULL;
 | 
			
		||||
  int* parent_tid = NULL;
 | 
			
		||||
  void* new_tls = NULL;
 | 
			
		||||
  int* child_tid = NULL;
 | 
			
		||||
 | 
			
		||||
    /* extract optional parameters - they are cumulative. */
 | 
			
		||||
    va_start(args, arg);
 | 
			
		||||
    if (flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID)) {
 | 
			
		||||
        parent_tidptr = va_arg(args, int*);
 | 
			
		||||
    }
 | 
			
		||||
    if (flags & (CLONE_SETTLS|CLONE_CHILD_SETTID)) {
 | 
			
		||||
        new_tls = va_arg(args, void*);
 | 
			
		||||
    }
 | 
			
		||||
    if (flags & CLONE_CHILD_SETTID) {
 | 
			
		||||
        child_tidptr = va_arg(args, int*);
 | 
			
		||||
    }
 | 
			
		||||
    va_end(args);
 | 
			
		||||
  // Extract any optional parameters required by the flags.
 | 
			
		||||
  va_list args;
 | 
			
		||||
  va_start(args, arg);
 | 
			
		||||
  if ((flags & (CLONE_PARENT_SETTID|CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
 | 
			
		||||
    parent_tid = va_arg(args, int*);
 | 
			
		||||
  }
 | 
			
		||||
  if ((flags & (CLONE_SETTLS|CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
 | 
			
		||||
    new_tls = va_arg(args, void*);
 | 
			
		||||
  }
 | 
			
		||||
  if ((flags & (CLONE_CHILD_SETTID|CLONE_CHILD_CLEARTID)) != 0) {
 | 
			
		||||
    child_tid = va_arg(args, int*);
 | 
			
		||||
  }
 | 
			
		||||
  va_end(args);
 | 
			
		||||
 | 
			
		||||
    return __bionic_clone(flags, child_stack, parent_tidptr, new_tls, child_tidptr, fn, arg);
 | 
			
		||||
  return __bionic_clone(flags, child_stack, parent_tid, new_tls, child_tid, fn, arg);
 | 
			
		||||
}
 | 
			
		||||
@@ -27,12 +27,11 @@
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <sys/syscall.h>
 | 
			
		||||
 | 
			
		||||
#include "private/libc_logging.h"
 | 
			
		||||
#include "pthread_internal.h"
 | 
			
		||||
 | 
			
		||||
#include "private/bionic_pthread.h"
 | 
			
		||||
 | 
			
		||||
extern "C" int __clone(int, void*, int*, void*, int*);
 | 
			
		||||
 | 
			
		||||
int fork() {
 | 
			
		||||
  // POSIX mandates that the timers of a fork child process be
 | 
			
		||||
  // disarmed, but not destroyed. To avoid a race condition, we're
 | 
			
		||||
@@ -42,18 +41,17 @@ int fork() {
 | 
			
		||||
  __bionic_atfork_run_prepare();
 | 
			
		||||
 | 
			
		||||
  pthread_internal_t* self = __get_thread();
 | 
			
		||||
#if defined(__x86_64__)
 | 
			
		||||
  int result = __clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, NULL, NULL, &(self->tid), NULL);
 | 
			
		||||
  int flags = CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD;
 | 
			
		||||
#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);
 | 
			
		||||
#else
 | 
			
		||||
  int result = __clone(CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, NULL, NULL, NULL, &(self->tid));
 | 
			
		||||
  int result = syscall(__NR_clone, flags, NULL, NULL, NULL, &(self->tid));
 | 
			
		||||
#endif
 | 
			
		||||
  if (result != 0) {  // Not a child process.
 | 
			
		||||
  if (result == 0) {
 | 
			
		||||
    __bionic_atfork_run_child();
 | 
			
		||||
  } else {
 | 
			
		||||
    __timer_table_start_stop(0);
 | 
			
		||||
    __bionic_atfork_run_parent();
 | 
			
		||||
  } else {
 | 
			
		||||
    // Fix the tid in the pthread_internal_t struct after a fork.
 | 
			
		||||
    __pthread_settid(pthread_self(), gettid());
 | 
			
		||||
    __bionic_atfork_run_child();
 | 
			
		||||
  }
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@
 | 
			
		||||
 | 
			
		||||
#include "private/bionic_atomic_inline.h"
 | 
			
		||||
#include "private/bionic_futex.h"
 | 
			
		||||
#include "private/bionic_pthread.h"
 | 
			
		||||
#include "private/bionic_time_conversions.h"
 | 
			
		||||
#include "private/bionic_tls.h"
 | 
			
		||||
#include "private/thread_private.h"
 | 
			
		||||
 
 | 
			
		||||
@@ -97,6 +97,5 @@ __LIBC_HIDDEN__ extern void __timer_table_start_stop(int);
 | 
			
		||||
__LIBC_HIDDEN__ extern void __bionic_atfork_run_prepare();
 | 
			
		||||
__LIBC_HIDDEN__ extern void __bionic_atfork_run_child();
 | 
			
		||||
__LIBC_HIDDEN__ extern void __bionic_atfork_run_parent();
 | 
			
		||||
__LIBC_HIDDEN__ extern int __pthread_settid(pthread_t, pid_t);
 | 
			
		||||
 | 
			
		||||
#endif /* _PTHREAD_INTERNAL_H_ */
 | 
			
		||||
 
 | 
			
		||||
@@ -73,14 +73,6 @@ pid_t __pthread_gettid(pthread_t t) {
 | 
			
		||||
  return reinterpret_cast<pthread_internal_t*>(t)->tid;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int __pthread_settid(pthread_t t, pid_t tid) {
 | 
			
		||||
  if (t == 0) {
 | 
			
		||||
    return EINVAL;
 | 
			
		||||
  }
 | 
			
		||||
  reinterpret_cast<pthread_internal_t*>(t)->tid = tid;
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Initialize 'ts' with the difference between 'abstime' and the current time
 | 
			
		||||
// according to 'clock'. Returns -1 if abstime already expired, or 0 otherwise.
 | 
			
		||||
int __timespec_to_absolute(timespec* ts, const timespec* abstime, clockid_t clock) {
 | 
			
		||||
 
 | 
			
		||||
@@ -38,7 +38,6 @@
 | 
			
		||||
 | 
			
		||||
#include "private/bionic_atomic_inline.h"
 | 
			
		||||
#include "private/bionic_futex.h"
 | 
			
		||||
#include "private/bionic_pthread.h"
 | 
			
		||||
#include "private/bionic_tls.h"
 | 
			
		||||
#include "private/thread_private.h"
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user