reference
-
linus介绍thread的帖子: http://www.evanjones.ca/software/threading-linus-msg.html
-
Professional Linux kernel architecture. Wolfgang Mauerer. 2008
nptl init flow
libc_2_19/nptl/pt-crti.S 1 /* Special .init and .fini section support for libpthread. 2 Copyright (C) 2012-2014 Free Software Foundation, Inc. 3 +-- 33 lines: This file is part of the GNU C Library.---------------------- 36 /* Arrange for __pthread_initialize_minimal_internal to be called at 37 libpthread startup, instead of conditionally calling 38 __gmon_start__. */ 39 40 #define PREINIT_FUNCTION __pthread_initialize_minimal_internal 41 #define PREINIT_FUNCTION_WEAK 0 42 43 #include <crti.S>
libc_2_19/ports/sysdeps/arm/crti.S 1 /* Special .init and .fini section support for ARM. 2 Copyright (C) 1995-2014 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 +-- 32 lines: The GNU C Library is free software; you can redistribute it and/or--------------------------------------------------------------------------------------- 36 /* crti.S puts a function prologue at the beginning of the .init and 37 .fini sections and defines global symbols for those addresses, so 38 they can be called as functions. The symbols _init and _fini are 39 magic and cause the linker to emit DT_INIT and DT_FINI. */ 40 41 /* Always build .init and .fini sections in ARM mode. */ 42 #define NO_THUMB 43 #include <libc-symbols.h> 44 #include <sysdep.h> 45 46 #ifndef PREINIT_FUNCTION 47 # define PREINIT_FUNCTION __gmon_start__ 48 #endif 49 50 #ifndef PREINIT_FUNCTION_WEAK 51 # define PREINIT_FUNCTION_WEAK 1 52 #endif 53 54 #if PREINIT_FUNCTION_WEAK 55 weak_extern (PREINIT_FUNCTION) 56 #else 57 .hidden PREINIT_FUNCTION 58 #endif 59 60 #if PREINIT_FUNCTION_WEAK 61 .p2align 2 62 .type call_weak_fn, %function 63 call_weak_fn: 64 ldr r3, .LGOT 65 ldr r2, .LGOT+4 66 .LPIC: 67 add r3, pc, r3 68 ldr r2, [r3, r2] 69 cmp r2, #0 70 bxeq lr 71 b PREINIT_FUNCTION 72 .p2align 2 73 .LGOT: 74 .word _GLOBAL_OFFSET_TABLE_-(.LPIC+8) 75 .word PREINIT_FUNCTION(GOT)76 #endif77 78 .section .init,"ax",%progbits 79 .p2align 2 80 .globl _init 81 .type _init, %function 82 _init: 83 push {r3, lr} 84 #if PREINIT_FUNCTION_WEAK85 bl call_weak_fn 86 #else 87 bl PREINIT_FUNCTION 88 #endif 89 90 .section .fini,"ax",%progbits 91 .p2align 2 92 .globl _fini 93 .type _fini, %function 94 _fini: 95 push {r3, lr}
pthread_functions
libc_2_19/nptl/nptl-init.c 81 static const struct pthread_functions pthread_functions = 82 { 83 .ptr_pthread_attr_destroy = __pthread_attr_destroy, 84 # if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) 85 .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0, 86 # endif 87 .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1, 88 .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate, 89 .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate, 90 +-- 49 lines: .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,------------------- 139 /* For now only the stack cache needs to be freed. */ 140 .ptr_freeres = nptl_freeres, 141 .ptr_set_robust = __nptl_set_robust 142 }; 143 # define ptr_pthread_functions &pthread_functions 144 #else 145 # define ptr_pthread_functions NULL 146 #endif 147
init function
279 void 280 __pthread_initialize_minimal_internal (void) 281 { 282 +-- 13 lines: #ifndef SHARED------------------------------------------------------------------------- 295 struct pthread *pd = THREAD_SELF; 296 INTERNAL_SYSCALL_DECL (err); 297 pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid); 298 THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]); 299 THREAD_SETMEM (pd, user_stack, true); 300 if (LLL_LOCK_INITIALIZER != 0) 301 THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER); 302 #if HP_TIMING_AVAIL 303 THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset)); 304 #endif 305 +-- 63 lines: Initialize the robust mutex data. ---------------------------------------------------- 368 /* Install the cancellation signal handler. If for some reason we 369 cannot install the handler we do not abort. Maybe we should, but 370 it is only asynchronous cancellation which is affected. */ 371 struct sigaction sa; 372 sa.sa_sigaction = sigcancel_handler; 373 sa.sa_flags = SA_SIGINFO; 374 __sigemptyset (&sa.sa_mask); 375 376 (void) __libc_sigaction (SIGCANCEL, &sa, NULL); 377 378 /* Install the handle to change the threads' uid/gid. */ 379 sa.sa_sigaction = sighandler_setxid; 380 sa.sa_flags = SA_SIGINFO | SA_RESTART; 381 382 (void) __libc_sigaction (SIGSETXID, &sa, NULL); 383 +-- 73 lines: The parent process might have left the signals blocked. Just in----------------------------------------------------------------------------------------- 456 __libc_pthread_init (&__fork_generation, __reclaim_stacks, 457 ptr_pthread_functions); 458 459 /* Determine whether the machine is SMP or not. */ 460 __is_smp = is_smp_system (); 461 } 462 strong_alias (__pthread_initialize_minimal_internal, 463 __pthread_initialize_minimal) 464