123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329 |
- #include <assert.h>
- #include <limits.h>
- #include <signal.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <sys/param.h>
- #include <sys/resource.h>
- #include <pthreadP.h>
- #include <atomic.h>
- #include <ldsodefs.h>
- #include <tls.h>
- #include <fork.h>
- #include <smp.h>
- #include <lowlevellock.h>
- #include <version.h>
- #ifndef __NR_set_tid_address
- #if defined __s390__
- # define __NR_set_tid_address 252
- #elif defined __ia64__
- # define __NR_set_tid_address 1233
- #elif defined __i386__
- # define __NR_set_tid_address 258
- #elif defined __x86_64__
- # define __NR_set_tid_address 218
- #elif defined __powerpc__
- # define __NR_set_tid_address 232
- #elif defined __sparc__
- # define __NR_set_tid_address 166
- #else
- # error "define __NR_set_tid_address"
- #endif
- #endif
- size_t __static_tls_size;
- size_t __static_tls_align_m1;
- static const char nptl_version[] __attribute_used__ = VERSION;
- #if defined USE_TLS && !defined SHARED
- extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
- #endif
- int
- __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact);
- #ifdef SHARED
- static const struct pthread_functions pthread_functions =
- {
- .ptr_pthread_attr_destroy = __pthread_attr_destroy,
- .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1,
- .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate,
- .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate,
- .ptr_pthread_attr_getinheritsched = __pthread_attr_getinheritsched,
- .ptr_pthread_attr_setinheritsched = __pthread_attr_setinheritsched,
- .ptr_pthread_attr_getschedparam = __pthread_attr_getschedparam,
- .ptr_pthread_attr_setschedparam = __pthread_attr_setschedparam,
- .ptr_pthread_attr_getschedpolicy = __pthread_attr_getschedpolicy,
- .ptr_pthread_attr_setschedpolicy = __pthread_attr_setschedpolicy,
- .ptr_pthread_attr_getscope = __pthread_attr_getscope,
- .ptr_pthread_attr_setscope = __pthread_attr_setscope,
- .ptr_pthread_condattr_destroy = __pthread_condattr_destroy,
- .ptr_pthread_condattr_init = __pthread_condattr_init,
- .ptr___pthread_cond_broadcast = __pthread_cond_broadcast,
- .ptr___pthread_cond_destroy = __pthread_cond_destroy,
- .ptr___pthread_cond_init = __pthread_cond_init,
- .ptr___pthread_cond_signal = __pthread_cond_signal,
- .ptr___pthread_cond_wait = __pthread_cond_wait,
- .ptr___pthread_cond_timedwait = __pthread_cond_timedwait,
- .ptr_pthread_equal = __pthread_equal,
- .ptr___pthread_exit = __pthread_exit,
- .ptr_pthread_getschedparam = __pthread_getschedparam,
- .ptr_pthread_setschedparam = __pthread_setschedparam,
- .ptr_pthread_mutex_destroy = __pthread_mutex_destroy,
- .ptr_pthread_mutex_init = __pthread_mutex_init,
- .ptr_pthread_mutex_lock = __pthread_mutex_lock,
- .ptr_pthread_mutex_unlock = __pthread_mutex_unlock,
- .ptr_pthread_self = __pthread_self,
- .ptr_pthread_setcancelstate = __pthread_setcancelstate,
- .ptr_pthread_setcanceltype = __pthread_setcanceltype,
- .ptr___pthread_cleanup_upto = __pthread_cleanup_upto,
- .ptr___pthread_once = __pthread_once_internal,
- .ptr___pthread_rwlock_rdlock = __pthread_rwlock_rdlock_internal,
- .ptr___pthread_rwlock_wrlock = __pthread_rwlock_wrlock_internal,
- .ptr___pthread_rwlock_unlock = __pthread_rwlock_unlock_internal,
- .ptr___pthread_key_create = __pthread_key_create_internal,
- .ptr___pthread_getspecific = __pthread_getspecific_internal,
- .ptr___pthread_setspecific = __pthread_setspecific_internal,
- .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer,
- .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore,
- .ptr_nthreads = &__nptl_nthreads,
- .ptr___pthread_unwind = &__pthread_unwind,
- .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd,
- .ptr__nptl_setxid = __nptl_setxid
- };
- # define ptr_pthread_functions &pthread_functions
- #else
- # define ptr_pthread_functions NULL
- #endif
- static void
- sigcancel_handler (int sig, siginfo_t *si, void *ctx)
- {
-
- if (sig != SIGCANCEL
- #ifdef __ASSUME_CORRECT_SI_PID
-
- || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
- #endif
- || si->si_code != SI_TKILL)
- return;
- struct pthread *self = THREAD_SELF;
- int oldval = THREAD_GETMEM (self, cancelhandling);
- while (1)
- {
-
- int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
- if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
-
- break;
- int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
- oldval);
- if (curval == oldval)
- {
-
- THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
- if ((newval & CANCELTYPE_BITMASK) != 0)
-
- __do_cancel ();
- break;
- }
- oldval = curval;
- }
- }
- struct xid_command *__xidcmd attribute_hidden;
- static void
- sighandler_setxid (int sig, siginfo_t *si, void *ctx)
- {
-
- if (sig != SIGSETXID
- #ifdef __ASSUME_CORRECT_SI_PID
-
- || si->si_pid != THREAD_GETMEM (THREAD_SELF, pid)
- #endif
- || si->si_code != SI_TKILL)
- return;
- INTERNAL_SYSCALL_DECL (err);
- INTERNAL_SYSCALL_NCS (__xidcmd->syscall_no, err, 3, __xidcmd->id[0],
- __xidcmd->id[1], __xidcmd->id[2]);
- if (atomic_decrement_val (&__xidcmd->cntr) == 0)
- lll_futex_wake (&__xidcmd->cntr, 1);
- }
- extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
- void
- __pthread_initialize_minimal_internal (void)
- {
- #ifndef SHARED
-
- __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
-
- __asm __volatile ("");
- #endif
-
- struct pthread *pd = THREAD_SELF;
- INTERNAL_SYSCALL_DECL (err);
- pd->pid = pd->tid = INTERNAL_SYSCALL (set_tid_address, err, 1, &pd->tid);
- THREAD_SETMEM (pd, specific[0], &pd->specific_1stblock[0]);
- THREAD_SETMEM (pd, user_stack, true);
- if (LLL_LOCK_INITIALIZER != 0)
- THREAD_SETMEM (pd, lock, LLL_LOCK_INITIALIZER);
- #if HP_TIMING_AVAIL
- THREAD_SETMEM (pd, cpuclock_offset, GL(dl_cpuclock_offset));
- #endif
-
- THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
-
- INIT_LIST_HEAD (&__stack_user);
- list_add (&pd->list, &__stack_user);
-
- struct sigaction sa;
- sa.sa_sigaction = sigcancel_handler;
- sa.sa_flags = SA_SIGINFO;
- __sigemptyset (&sa.sa_mask);
- (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
-
- sa.sa_sigaction = sighandler_setxid;
- sa.sa_flags = SA_SIGINFO | SA_RESTART;
- (void) __libc_sigaction (SIGSETXID, &sa, NULL);
-
- __sigaddset (&sa.sa_mask, SIGCANCEL);
- __sigaddset (&sa.sa_mask, SIGSETXID);
- (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &sa.sa_mask,
- NULL, _NSIG / 8);
-
- size_t static_tls_align;
- _dl_get_tls_static_info (&__static_tls_size, &static_tls_align);
-
- if (STACK_ALIGN > static_tls_align)
- static_tls_align = STACK_ALIGN;
- __static_tls_align_m1 = static_tls_align - 1;
- __static_tls_size = roundup (__static_tls_size, static_tls_align);
-
- struct rlimit limit;
- if (getrlimit (RLIMIT_STACK, &limit) != 0
- || limit.rlim_cur == RLIM_INFINITY)
-
- limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
- else if (limit.rlim_cur < PTHREAD_STACK_MIN)
-
- limit.rlim_cur = PTHREAD_STACK_MIN;
-
- const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
- const size_t minstack = pagesz + __static_tls_size + MINIMAL_REST_STACK;
- if (limit.rlim_cur < minstack)
- limit.rlim_cur = minstack;
-
- limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
- __default_stacksize = limit.rlim_cur;
- #ifdef SHARED
-
- *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
- GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
- #endif
- GL(dl_init_static_tls) = &__pthread_init_static_tls;
-
- #ifndef TLS_MULTIPLE_THREADS_IN_TCB
- __libc_multiple_threads_ptr =
- #endif
- __libc_pthread_init (&__fork_generation, __reclaim_stacks,
- ptr_pthread_functions);
-
- __is_smp = is_smp_system ();
- }
- strong_alias (__pthread_initialize_minimal_internal,
- __pthread_initialize_minimal)
|