123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include <assert.h>
- #include <errno.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 <version.h>
- #include <smp.h>
- #include <lowlevellock.h>
- #include <bits/kernel-features.h>
- #include <stdio.h>
- size_t __static_tls_size;
- size_t __static_tls_align_m1;
- #ifndef __ASSUME_SET_ROBUST_LIST
- int __set_robust_list_avail;
- # define set_robust_list_not_avail() \
- __set_robust_list_avail = -1
- #else
- # define set_robust_list_not_avail() do { } while (0)
- #endif
- #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
- int __have_futex_clock_realtime;
- # define __set_futex_clock_realtime() \
- __have_futex_clock_realtime = 1
- #else
- #define __set_futex_clock_realtime() do { } while (0)
- #endif
- static const char nptl_version[] __attribute_used__ = VERSION;
- static void
- sigcancel_handler (int sig, siginfo_t *si, void *ctx)
- {
-
- if (sig != SIGCANCEL
- || si->si_pid != getpid()
- || 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
- || si->si_pid != getpid()
- || 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]);
-
- struct pthread *self = THREAD_SELF;
- int flags, newval;
- do
- {
- flags = THREAD_GETMEM (self, cancelhandling);
- newval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
- flags & ~SETXID_BITMASK, flags);
- }
- while (flags != newval);
-
- self->setxid_futex = 1;
- lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
- if (atomic_decrement_val (&__xidcmd->cntr) == 0)
- lll_futex_wake (&__xidcmd->cntr, 1, LLL_PRIVATE);
- }
- extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
- static bool __nptl_initial_report_events __attribute_used__;
- void __pthread_initialize_minimal_internal (void) attribute_hidden;
- void
- __pthread_initialize_minimal_internal (void)
- {
- static int initialized = 0;
- if (initialized)
- return;
- initialized = 1;
-
- struct pthread *pd = THREAD_SELF;
- INTERNAL_SYSCALL_DECL (err);
- 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);
-
- #ifdef __PTHREAD_MUTEX_HAVE_PREV
- pd->robust_prev = &pd->robust_head;
- #endif
- pd->robust_head.list = &pd->robust_head;
- #ifdef __NR_set_robust_list
- pd->robust_head.futex_offset = (offsetof (pthread_mutex_t, __data.__lock)
- - offsetof (pthread_mutex_t,
- __data.__list.__next));
- int res = INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
- sizeof (struct robust_list_head));
- if (INTERNAL_SYSCALL_ERROR_P (res, err))
- #endif
- set_robust_list_not_avail ();
- #ifndef __ASSUME_PRIVATE_FUTEX
-
- {
- int word = 0;
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
- word = INTERNAL_SYSCALL (futex_time64, err, 3, &word,
- FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
- #else
- word = INTERNAL_SYSCALL (futex, err, 3, &word,
- FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
- #endif
- if (!INTERNAL_SYSCALL_ERROR_P (word, err))
- THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
- }
-
- if (THREAD_GETMEM (pd, header.private_futex) != 0)
- #endif
- #ifndef __ASSUME_FUTEX_CLOCK_REALTIME
- {
- int word = 0;
-
- #if defined(__UCLIBC_USE_TIME64__) && defined(__NR_futex_time64)
- word = INTERNAL_SYSCALL (futex_time64, err, 5, &word,
- FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
- | FUTEX_PRIVATE_FLAG, 1, NULL, 0);
- #else
- word = INTERNAL_SYSCALL (futex, err, 5, &word,
- FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
- | FUTEX_PRIVATE_FLAG, 1, NULL, 0);
- #endif
- assert (INTERNAL_SYSCALL_ERROR_P (word, err));
- if (INTERNAL_SYSCALL_ERRNO (word, err) != ENOSYS)
- __set_futex_clock_realtime ();
- }
- #endif
-
- THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
-
- INIT_LIST_HEAD (&__stack_user);
- list_add (&pd->list, &__stack_user);
-
- THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
-
- 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 = __PTHREADS_STACK_DEFAULT_SIZE__;
- if (limit.rlim_cur < PTHREAD_STACK_MIN)
-
- limit.rlim_cur = PTHREAD_STACK_MIN;
-
- if (limit.rlim_cur > __PTHREADS_STACK_DEFAULT_SIZE__)
- limit.rlim_cur = __PTHREADS_STACK_DEFAULT_SIZE__;
-
- #ifdef SHARED
- extern size_t GLRO(dl_pagesize);
- const uintptr_t pagesz = GLRO(dl_pagesize);
- #else
- const uintptr_t pagesz = sysconf (_SC_PAGESIZE);
- #endif
- 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);
-
- __is_smp = is_smp_system ();
-
- {
- FILE *fp;
- _stdio_user_locking = 0;
- for (fp = _stdio_openlist; fp != NULL; fp = fp->__nextopen) {
- if (fp->__user_locking != 1) {
- fp->__user_locking = 0;
- }
- }
- }
- }
- strong_alias (__pthread_initialize_minimal_internal,
- __pthread_initialize_minimal)
- size_t
- __pthread_get_minstack (const pthread_attr_t *attr)
- {
- return __static_tls_size + PTHREAD_STACK_MIN;
- }
|