diff options
Diffstat (limited to 'nptl')
31 files changed, 457 insertions, 146 deletions
diff --git a/nptl/ChangeLog b/nptl/ChangeLog index c4f6c630cc..707744a657 100644 --- a/nptl/ChangeLog +++ b/nptl/ChangeLog @@ -1,3 +1,123 @@ +2013-03-19 Siddhesh Poyarekar <siddhesh@redhat.com> + + * allocatestack.c (allocate_stack): Use __default_pthread_attr + instead of __default_stacksize. + * nptl-init.c (__pthread_initialize_minimal_internal): + Likewise. Initialize guardsize. + * pthreadP.h (__default_pthread_attr): Declare. + * pthread_attr_getstacksize.c (__pthread_attr_getstacksize): + Use __default_pthread_attr instead of __default_stacksize. + * pthread_create.c (default_attr): Remove. + (__pthread_create_2_1): Use __default_pthread_attr instead of + default_attr. + * vars.c (__default_stacksize): Remove. + (__default_pthread_attr): New static variable to store + default thread attributes. + +2013-03-18 Siddhesh Poyarekar <siddhesh@redhat.com> + + * pthread_barrier_init.c (default_attr): Rename to + default_barrierattr. + (pthread_barrier_init): Adjust for the rename. + * pthread_mutex_init.c (default_attr): Rename to + default_mutexattr. + (__pthread_mutex_init): Adjust for the rename. + * pthread_rwlock_init.c (default_attr): Rebane to + default_rwlockattr. + (__pthread_rwlock_init): Adjust for the rename. + +2013-03-12 Carlos O'Donell <carlos@redhat.com> + + * sysdeps/unix/sysv/linux/lowlevellock.c: Include <atomic.h>. + +2013-03-04 Roland McGrath <roland@hack.frob.com> + + * sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h: + Change multiple inclusion guard to _LINUX_I686_DL_SYSDEP_H. + Use #include_next. + (HAVE_DL_DISCOVER_OSVERSION): Remove definition, now redundant. + (RTLD_PRIVATE_ERRNO): Likewise. + (NEED_DL_SYSINFO, DL_SYSINFO_DEFAULT, DL_SYSINFO_IMPLEMENTATION): + Move macros and associated declaration to ... + * sysdeps/unix/sysv/linux/i386/dl-sysdep.h: ... here. + Change multiple include guard to _LINUX_I386_DL_SYSDEP_H. + Use #include_next. + +2013-03-01 Carlos O'Donell <carlos@redhat.com> + + * Makefile (tests): Revert last change. + (tst-pthread-stack-env-ENV): Likewise. + * nptl-init.c (set_default_stacksize): Likewise. + (__pthread_initialize_minimal_internal): Likewise. + * tst-pthread-stack-env.c: Likewise. + +2013-03-01 Siddhesh Poyarekar <siddhesh@redhat.com> + + * tst-oddstacklimit.c: Include stdlib.h. + + * Makefile (tests): Add tst-pthread-stack-env. + (tst-pthread-stack-env-ENV): Set environment for test. + * nptl-init.c (set_default_stacksize): New function. + (__pthread_initialize_minimal_internal): Accept ARGC, ARGV and + ENVP. Initialize __ENVIRON and set __DEFAULT_STACKSIZE. + * tst-pthread-stack-env.c: New test case. + +2013-02-21 David S. Miller <davem@davemloft.net> + + * sysdeps/unix/sysv/linux/sparc/lowlevellock.h + (FUTEX_WAIT_REQUEUE_PI): Define. + (FUTEX_CMP_REQUEUE_PI): Likewise. + (lll_futex_wait_requeue_pi): Likewise. + (lll_futex_timed_wait_requeue_pi): Likewise. + (lll_futex_cmp_requeue_pi): Likewise. + +2013-02-21 Carlos O'Donell <carlos@redhat.com> + + * sysdeps/unix/sysv/linux/fork.c: Fix comment typo. + +2013-02-18 Siddhesh Poyarekar <siddhesh@redhat.com> + + * sysdeps/pthread/tst-timer.c: Include stdlib.h for declaration + of exit. + * tst-barrier4.c: Likewise. + * tst-robust7.c: Likewise. + + [BZ #14920] + * pthreadP.h (USE_REQUEUE_PI): New macro to check if mutex is + PI-aware. + * pthread_cond_broadcast.c (__pthread_cond_broadcast): Use + PI-aware futex operations if available and mutex is PI-aware. + * pthread_cond_signal.c (__pthread_cond_signal): Likewise. + * nptl/pthread_cond_timedwait.c (__pthread_cond_timedwait): + Likewise. + * pthread_cond_wait.c (__condvar_cleanup): Adjust lock if + cancellation occurred just after futex returned successfully + from a PI operation with the mutex held. + (__pthread_cond_wait): Use PI-aware futex operations if + available and mutex is PI-aware. + * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h + (FUTEX_WAIT_REQUEUE_PI): Define. + (FUTEX_CMP_REQUEUE_PI): Likewise. + (lll_futex_wait_requeue_pi): Likewise. + (lll_futex_timed_wait_requeue_pi): Likewise. + (lll_futex_cmp_requeue_pi): Likewise. + * nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h + (FUTEX_WAIT_REQUEUE_PI): Define. + (FUTEX_CMP_REQUEUE_PI): Likewise. + (lll_futex_wait_requeue_pi): Likewise. + (lll_futex_timed_wait_requeue_pi): Likewise. + (lll_futex_cmp_requeue_pi): Likewise. + * sysdeps/unix/sysv/linux/kernel-features.h: Define + __ASSUME_REQUEUE_PI for Linux version higher than 2.6.31. + +2013-02-04 Andreas Schwab <schwab@suse.de> + + [BZ #14142] + * tst-cancel14.c: Include <sys/time.h>. + * tst-cancel15.c: Likewise. + * tst-mutex9.c: Include <stdint.h>, <stdlib.h> and <sys/time.h>. + * tst-stackguard1.c: Include <tls.h> + 2013-01-16 Andreas Schwab <schwab@suse.de> [BZ #14327] diff --git a/nptl/Makeconfig b/nptl/Makeconfig index 7be9b0d7c4..2a1399d74b 100644 --- a/nptl/Makeconfig +++ b/nptl/Makeconfig @@ -24,7 +24,6 @@ have-thread-library = yes shared-thread-library = $(common-objpfx)nptl/libpthread_nonshared.a \ $(common-objpfx)nptl/libpthread.so static-thread-library = $(common-objpfx)nptl/libpthread.a -bounded-thread-library = $(common-objpfx)nptl/libpthread_b.a rpath-dirs += nptl diff --git a/nptl/allocatestack.c b/nptl/allocatestack.c index 31c88291ae..56bf2570f8 100644 --- a/nptl/allocatestack.c +++ b/nptl/allocatestack.c @@ -358,7 +358,7 @@ allocate_stack (const struct pthread_attr *attr, struct pthread **pdp, /* Get the stack size from the attribute if it is set. Otherwise we use the default we determined at start time. */ - size = attr->stacksize ?: __default_stacksize; + size = attr->stacksize ?: __default_pthread_attr.stacksize; /* Get memory for the stack. */ if (__builtin_expect (attr->flags & ATTR_FLAG_STACKADDR, 0)) diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 19e6616420..63fb729fc6 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -423,7 +423,8 @@ __pthread_initialize_minimal_internal (void) /* Round the resource limit up to page size. */ limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz; - __default_stacksize = limit.rlim_cur; + __default_pthread_attr.stacksize = limit.rlim_cur; + __default_pthread_attr.guardsize = GLRO (dl_pagesize); #ifdef SHARED /* Transfer the old value from the dynamic linker's internal location. */ diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 993a79e250..954b54a50a 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -147,8 +147,8 @@ enum /* Internal variables. */ -/* Default stack size. */ -extern size_t __default_stacksize attribute_hidden; +/* Default pthread attributes. */ +extern struct pthread_attr __default_pthread_attr attribute_hidden; /* Size and alignment of static TLS block. */ extern size_t __static_tls_size attribute_hidden; @@ -577,4 +577,16 @@ extern void __wait_lookup_done (void) attribute_hidden; # define PTHREAD_STATIC_FN_REQUIRE(name) __asm (".globl " #name); #endif +/* Test if the mutex is suitable for the FUTEX_WAIT_REQUEUE_PI operation. */ +#if (defined lll_futex_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) +# define USE_REQUEUE_PI(mut) \ + ((mut) && (mut) != (void *) ~0l \ + && (((mut)->__data.__kind \ + & (PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP)) \ + == PTHREAD_MUTEX_PRIO_INHERIT_NP)) +#else +# define USE_REQUEUE_PI(mut) 0 +#endif + #endif /* pthreadP.h */ diff --git a/nptl/pthread_attr_getstacksize.c b/nptl/pthread_attr_getstacksize.c index 6df70623e8..42d3f8f44c 100644 --- a/nptl/pthread_attr_getstacksize.c +++ b/nptl/pthread_attr_getstacksize.c @@ -32,7 +32,7 @@ __pthread_attr_getstacksize (attr, stacksize) /* If the user has not set a stack size we return what the system will use as the default. */ - *stacksize = iattr->stacksize ?: __default_stacksize; + *stacksize = iattr->stacksize ?: __default_pthread_attr.stacksize; return 0; } diff --git a/nptl/pthread_barrier_init.c b/nptl/pthread_barrier_init.c index d5891fd41e..6d2910ef95 100644 --- a/nptl/pthread_barrier_init.c +++ b/nptl/pthread_barrier_init.c @@ -22,7 +22,7 @@ #include <kernel-features.h> -static const struct pthread_barrierattr default_attr = +static const struct pthread_barrierattr default_barrierattr = { .pshared = PTHREAD_PROCESS_PRIVATE }; @@ -42,7 +42,7 @@ pthread_barrier_init (barrier, attr, count) const struct pthread_barrierattr *iattr = (attr != NULL ? iattr = (struct pthread_barrierattr *) attr - : &default_attr); + : &default_barrierattr); if (iattr->pshared != PTHREAD_PROCESS_PRIVATE && __builtin_expect (iattr->pshared != PTHREAD_PROCESS_SHARED, 0)) diff --git a/nptl/pthread_cond_broadcast.c b/nptl/pthread_cond_broadcast.c index 968ee03da7..0702ec0ec2 100644 --- a/nptl/pthread_cond_broadcast.c +++ b/nptl/pthread_cond_broadcast.c @@ -53,34 +53,37 @@ __pthread_cond_broadcast (cond) /* We are done. */ lll_unlock (cond->__data.__lock, pshared); - /* Do not use requeue for pshared condvars. */ - if (cond->__data.__mutex == (void *) ~0l) - goto wake_all; - /* Wake everybody. */ pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex; - /* XXX: Kernel so far doesn't support requeue to PI futex. */ - /* XXX: Kernel so far can only requeue to the same type of futex, - in this case private (we don't requeue for pshared condvars). */ - if (__builtin_expect (mut->__data.__kind - & (PTHREAD_MUTEX_PRIO_INHERIT_NP - | PTHREAD_MUTEX_PSHARED_BIT), 0)) + /* Do not use requeue for pshared condvars. */ + if (mut == (void *) ~0l + || PTHREAD_MUTEX_PSHARED (mut) & PTHREAD_MUTEX_PSHARED_BIT) goto wake_all; - /* lll_futex_requeue returns 0 for success and non-zero - for errors. */ - if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, - INT_MAX, &mut->__data.__lock, - futex_val, LLL_PRIVATE), 0)) +#if (defined lll_futex_cmp_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP; + pi_flag &= mut->__data.__kind; + + if (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP) { - /* The requeue functionality is not available. */ - wake_all: - lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared); + if (lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, INT_MAX, + &mut->__data.__lock, futex_val, + LLL_PRIVATE) == 0) + return 0; } - - /* That's all. */ - return 0; + else +#endif + /* lll_futex_requeue returns 0 for success and non-zero + for errors. */ + if (!__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1, + INT_MAX, &mut->__data.__lock, + futex_val, LLL_PRIVATE), 0)) + return 0; + +wake_all: + lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared); } /* We are done. */ diff --git a/nptl/pthread_cond_signal.c b/nptl/pthread_cond_signal.c index 908a2acfaf..102d0b380c 100644 --- a/nptl/pthread_cond_signal.c +++ b/nptl/pthread_cond_signal.c @@ -47,12 +47,35 @@ __pthread_cond_signal (cond) ++cond->__data.__wakeup_seq; ++cond->__data.__futex; - /* Wake one. */ - if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1, - 1, &cond->__data.__lock, - pshared), 0)) - return 0; +#if (defined lll_futex_cmp_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + int pi_flag = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NP; + pthread_mutex_t *mut = cond->__data.__mutex; + /* Do not use requeue for pshared condvars. */ + if (mut != (void *) ~0l) + pi_flag &= mut->__data.__kind; + + if (__builtin_expect (pi_flag == PTHREAD_MUTEX_PRIO_INHERIT_NP, 0) + /* This can only really fail with a ENOSYS, since nobody can modify + futex while we have the cond_lock. */ + && lll_futex_cmp_requeue_pi (&cond->__data.__futex, 1, 0, + &mut->__data.__lock, + cond->__data.__futex, pshared) == 0) + { + lll_unlock (cond->__data.__lock, pshared); + return 0; + } + else +#endif + /* Wake one. */ + if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, + 1, 1, + &cond->__data.__lock, + pshared), 0)) + return 0; + + /* Fallback if neither of them work. */ lll_futex_wake (&cond->__data.__futex, 1, pshared); } diff --git a/nptl/pthread_cond_timedwait.c b/nptl/pthread_cond_timedwait.c index 0f52bd885c..0a2d092e6c 100644 --- a/nptl/pthread_cond_timedwait.c +++ b/nptl/pthread_cond_timedwait.c @@ -64,6 +64,11 @@ __pthread_cond_timedwait (cond, mutex, abstime) int pshared = (cond->__data.__mutex == (void *) ~0l) ? LLL_SHARED : LLL_PRIVATE; +#if (defined lll_futex_timed_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + int pi_flag = 0; +#endif + /* Make sure we are alone. */ lll_lock (cond->__data.__lock, pshared); @@ -155,17 +160,46 @@ __pthread_cond_timedwait (cond, mutex, abstime) /* Enable asynchronous cancellation. Required by the standard. */ cbuffer.oldtype = __pthread_enable_asynccancel (); +/* REQUEUE_PI was implemented after FUTEX_CLOCK_REALTIME, so it is sufficient + to check just the former. */ +#if (defined lll_futex_timed_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + /* If pi_flag remained 1 then it means that we had the lock and the mutex + but a spurious waker raced ahead of us. Give back the mutex before + going into wait again. */ + if (pi_flag) + { + __pthread_mutex_cond_lock_adjust (mutex); + __pthread_mutex_unlock_usercnt (mutex, 0); + } + pi_flag = USE_REQUEUE_PI (mutex); + + if (pi_flag) + { + unsigned int clockbit = (cond->__data.__nwaiters & 1 + ? 0 : FUTEX_CLOCK_REALTIME); + err = lll_futex_timed_wait_requeue_pi (&cond->__data.__futex, + futex_val, abstime, clockbit, + &mutex->__data.__lock, + pshared); + pi_flag = (err == 0); + } + else +#endif + + { #if (!defined __ASSUME_FUTEX_CLOCK_REALTIME \ || !defined lll_futex_timed_wait_bitset) - /* Wait until woken by signal or broadcast. */ - err = lll_futex_timed_wait (&cond->__data.__futex, - futex_val, &rt, pshared); + /* Wait until woken by signal or broadcast. */ + err = lll_futex_timed_wait (&cond->__data.__futex, + futex_val, &rt, pshared); #else - unsigned int clockbit = (cond->__data.__nwaiters & 1 - ? 0 : FUTEX_CLOCK_REALTIME); - err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val, - abstime, clockbit, pshared); + unsigned int clockbit = (cond->__data.__nwaiters & 1 + ? 0 : FUTEX_CLOCK_REALTIME); + err = lll_futex_timed_wait_bitset (&cond->__data.__futex, futex_val, + abstime, clockbit, pshared); #endif + } /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype); @@ -217,7 +251,16 @@ __pthread_cond_timedwait (cond, mutex, abstime) __pthread_cleanup_pop (&buffer, 0); /* Get the mutex before returning. */ - err = __pthread_mutex_cond_lock (mutex); +#if (defined lll_futex_timed_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + if (pi_flag) + { + __pthread_mutex_cond_lock_adjust (mutex); + err = 0; + } + else +#endif + err = __pthread_mutex_cond_lock (mutex); return err ?: result; } diff --git a/nptl/pthread_cond_wait.c b/nptl/pthread_cond_wait.c index 0ae320cb83..01d42d7834 100644 --- a/nptl/pthread_cond_wait.c +++ b/nptl/pthread_cond_wait.c @@ -26,7 +26,6 @@ #include <shlib-compat.h> #include <stap-probe.h> - struct _condvar_cleanup_buffer { int oldtype; @@ -85,8 +84,15 @@ __condvar_cleanup (void *arg) lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared); /* Get the mutex before returning unless asynchronous cancellation - is in effect. */ - __pthread_mutex_cond_lock (cbuffer->mutex); + is in effect. We don't try to get the mutex if we already own it. */ + if (!(USE_REQUEUE_PI (cbuffer->mutex)) + || ((cbuffer->mutex->__data.__lock & FUTEX_TID_MASK) + != THREAD_GETMEM (THREAD_SELF, tid))) + { + __pthread_mutex_cond_lock (cbuffer->mutex); + } + else + __pthread_mutex_cond_lock_adjust (cbuffer->mutex); } @@ -101,6 +107,11 @@ __pthread_cond_wait (cond, mutex) int pshared = (cond->__data.__mutex == (void *) ~0l) ? LLL_SHARED : LLL_PRIVATE; +#if (defined lll_futex_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + int pi_flag = 0; +#endif + LIBC_PROBE (cond_wait, 2, cond, mutex); /* Make sure we are alone. */ @@ -144,15 +155,36 @@ __pthread_cond_wait (cond, mutex) do { unsigned int futex_val = cond->__data.__futex; - /* Prepare to wait. Release the condvar futex. */ lll_unlock (cond->__data.__lock, pshared); /* Enable asynchronous cancellation. Required by the standard. */ cbuffer.oldtype = __pthread_enable_asynccancel (); - /* Wait until woken by signal or broadcast. */ - lll_futex_wait (&cond->__data.__futex, futex_val, pshared); +#if (defined lll_futex_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + /* If pi_flag remained 1 then it means that we had the lock and the mutex + but a spurious waker raced ahead of us. Give back the mutex before + going into wait again. */ + if (pi_flag) + { + __pthread_mutex_cond_lock_adjust (mutex); + __pthread_mutex_unlock_usercnt (mutex, 0); + } + pi_flag = USE_REQUEUE_PI (mutex); + + if (pi_flag) + { + err = lll_futex_wait_requeue_pi (&cond->__data.__futex, + futex_val, &mutex->__data.__lock, + pshared); + + pi_flag = (err == 0); + } + else +#endif + /* Wait until woken by signal or broadcast. */ + lll_futex_wait (&cond->__data.__futex, futex_val, pshared); /* Disable asynchronous cancellation. */ __pthread_disable_asynccancel (cbuffer.oldtype); @@ -189,8 +221,17 @@ __pthread_cond_wait (cond, mutex) /* The cancellation handling is back to normal, remove the handler. */ __pthread_cleanup_pop (&buffer, 0); - /* Get the mutex before returning. */ - return __pthread_mutex_cond_lock (mutex); + /* Get the mutex before returning. Not needed for PI. */ +#if (defined lll_futex_wait_requeue_pi \ + && defined __ASSUME_REQUEUE_PI) + if (pi_flag) + { + __pthread_mutex_cond_lock_adjust (mutex); + return 0; + } + else +#endif + return __pthread_mutex_cond_lock (mutex); } versioned_symbol (libpthread, __pthread_cond_wait, pthread_cond_wait, diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c index 4fe0755079..c18278cf08 100644 --- a/nptl/pthread_create.c +++ b/nptl/pthread_create.c @@ -311,6 +311,9 @@ start_thread (void *arg) #endif } + /* Call destructors for the thread_local TLS variables. */ + __call_tls_dtors (); + /* Run the destructor for the thread-local data. */ __nptl_deallocate_tsd (); @@ -432,15 +435,6 @@ start_thread (void *arg) } -/* Default thread attributes for the case when the user does not - provide any. */ -static const struct pthread_attr default_attr = - { - /* Just some value > 0 which gets rounded to the nearest page size. */ - .guardsize = 1, - }; - - int __pthread_create_2_1 (newthread, attr, start_routine, arg) pthread_t *newthread; @@ -454,7 +448,7 @@ __pthread_create_2_1 (newthread, attr, start_routine, arg) if (iattr == NULL) /* Is this the best idea? On NUMA machines this could mean accessing far-away memory. */ - iattr = &default_attr; + iattr = &__default_pthread_attr; struct pthread *pd = NULL; int err = ALLOCATE_STACK (iattr, &pd); diff --git a/nptl/pthread_mutex_init.c b/nptl/pthread_mutex_init.c index 36da3f8bfb..174d900dc8 100644 --- a/nptl/pthread_mutex_init.c +++ b/nptl/pthread_mutex_init.c @@ -24,7 +24,7 @@ #include <stap-probe.h> -static const struct pthread_mutexattr default_attr = +static const struct pthread_mutexattr default_mutexattr = { /* Default is a normal mutex, not shared between processes. */ .mutexkind = PTHREAD_MUTEX_NORMAL @@ -45,7 +45,8 @@ __pthread_mutex_init (mutex, mutexattr) assert (sizeof (pthread_mutex_t) <= __SIZEOF_PTHREAD_MUTEX_T); - imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr; + imutexattr = ((const struct pthread_mutexattr *) mutexattr + ?: &default_mutexattr); /* Sanity checks. */ switch (__builtin_expect (imutexattr->mutexkind diff --git a/nptl/pthread_rwlock_init.c b/nptl/pthread_rwlock_init.c index 16bfe2d757..29bef71db3 100644 --- a/nptl/pthread_rwlock_init.c +++ b/nptl/pthread_rwlock_init.c @@ -21,7 +21,7 @@ #include <kernel-features.h> -static const struct pthread_rwlockattr default_attr = +static const struct pthread_rwlockattr default_rwlockattr = { .lockkind = PTHREAD_RWLOCK_DEFAULT_NP, .pshared = PTHREAD_PROCESS_PRIVATE @@ -35,7 +35,7 @@ __pthread_rwlock_init (rwlock, attr) { const struct pthread_rwlockattr *iattr; - iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_attr; + iattr = ((const struct pthread_rwlockattr *) attr) ?: &default_rwlockattr; memset (rwlock, '\0', sizeof (*rwlock)); diff --git a/nptl/sysdeps/pthread/bits/libc-lockP.h b/nptl/sysdeps/pthread/bits/libc-lockP.h index 31a40aa982..2781e191ec 100644 --- a/nptl/sysdeps/pthread/bits/libc-lockP.h +++ b/nptl/sysdeps/pthread/bits/libc-lockP.h @@ -375,31 +375,30 @@ extern int __pthread_atfork (void (*__prepare) (void), single-threaded processes. */ #ifndef __NO_WEAK_PTHREAD_ALIASES # ifdef weak_extern -# include <bp-sym.h> -weak_extern (BP_SYM (__pthread_mutex_init)) -weak_extern (BP_SYM (__pthread_mutex_destroy)) -weak_extern (BP_SYM (__pthread_mutex_lock)) -weak_extern (BP_SYM (__pthread_mutex_trylock)) -weak_extern (BP_SYM (__pthread_mutex_unlock)) -weak_extern (BP_SYM (__pthread_mutexattr_init)) -weak_extern (BP_SYM (__pthread_mutexattr_destroy)) -weak_extern (BP_SYM (__pthread_mutexattr_settype)) -weak_extern (BP_SYM (__pthread_rwlock_init)) -weak_extern (BP_SYM (__pthread_rwlock_destroy)) -weak_extern (BP_SYM (__pthread_rwlock_rdlock)) -weak_extern (BP_SYM (__pthread_rwlock_tryrdlock)) -weak_extern (BP_SYM (__pthread_rwlock_wrlock)) -weak_extern (BP_SYM (__pthread_rwlock_trywrlock)) -weak_extern (BP_SYM (__pthread_rwlock_unlock)) -weak_extern (BP_SYM (__pthread_key_create)) -weak_extern (BP_SYM (__pthread_setspecific)) -weak_extern (BP_SYM (__pthread_getspecific)) -weak_extern (BP_SYM (__pthread_once)) +weak_extern (__pthread_mutex_init) +weak_extern (__pthread_mutex_destroy) +weak_extern (__pthread_mutex_lock) +weak_extern (__pthread_mutex_trylock) +weak_extern (__pthread_mutex_unlock) +weak_extern (__pthread_mutexattr_init) +weak_extern (__pthread_mutexattr_destroy) +weak_extern (__pthread_mutexattr_settype) +weak_extern (__pthread_rwlock_init) +weak_extern (__pthread_rwlock_destroy) +weak_extern (__pthread_rwlock_rdlock) +weak_extern (__pthread_rwlock_tryrdlock) +weak_extern (__pthread_rwlock_wrlock) +weak_extern (__pthread_rwlock_trywrlock) +weak_extern (__pthread_rwlock_unlock) +weak_extern (__pthread_key_create) +weak_extern (__pthread_setspecific) +weak_extern (__pthread_getspecific) +weak_extern (__pthread_once) weak_extern (__pthread_initialize) weak_extern (__pthread_atfork) -weak_extern (BP_SYM (_pthread_cleanup_push_defer)) -weak_extern (BP_SYM (_pthread_cleanup_pop_restore)) -weak_extern (BP_SYM (pthread_setcancelstate)) +weak_extern (_pthread_cleanup_push_defer) +weak_extern (_pthread_cleanup_pop_restore) +weak_extern (pthread_setcancelstate) # else # pragma weak __pthread_mutex_init # pragma weak __pthread_mutex_destroy diff --git a/nptl/sysdeps/pthread/tst-timer.c b/nptl/sysdeps/pthread/tst-timer.c index f46addd791..fa1b6e72a3 100644 --- a/nptl/sysdeps/pthread/tst-timer.c +++ b/nptl/sysdeps/pthread/tst-timer.c @@ -22,6 +22,7 @@ #include <stdio.h> #include <time.h> #include <unistd.h> +#include <stdlib.h> static void diff --git a/nptl/sysdeps/unix/sysv/linux/fork.c b/nptl/sysdeps/unix/sysv/linux/fork.c index 05f3dce03b..ff089422e4 100644 --- a/nptl/sysdeps/unix/sysv/linux/fork.c +++ b/nptl/sysdeps/unix/sysv/linux/fork.c @@ -35,7 +35,7 @@ unsigned long int *__fork_generation_pointer; -/* The single linked list of all currently registered for handlers. */ +/* The single linked list of all currently registered fork handlers. */ struct fork_handler *__fork_handlers; diff --git a/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h index 29a77a08fa..a89eb0a62f 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h @@ -16,12 +16,31 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _DL_SYSDEP_H -# include "i686/dl-sysdep.h" +#ifndef _LINUX_I386_DL_SYSDEP_H -/* sysenter/syscall is not useful on i386 through i586, but the dynamic - linker and dl code in libc.a has to be able to load i686 compiled - libraries. */ -# undef USE_DL_SYSINFO +#include_next <dl-sysdep.h> + +/* Traditionally system calls have been made using int $0x80. A + second method was introduced which, if possible, will use the + sysenter/syscall instructions. To signal the presence and where to + find the code the kernel passes an AT_SYSINFO value in the + auxiliary vector to the application. */ +#define NEED_DL_SYSINFO 1 + +#ifndef __ASSEMBLER__ +extern void _dl_sysinfo_int80 (void) attribute_hidden; +# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80 +# define DL_SYSINFO_IMPLEMENTATION \ + asm (".text\n\t" \ + ".type _dl_sysinfo_int80,@function\n\t" \ + ".hidden _dl_sysinfo_int80\n" \ + CFI_STARTPROC "\n" \ + "_dl_sysinfo_int80:\n\t" \ + "int $0x80;\n\t" \ + "ret;\n\t" \ + CFI_ENDPROC "\n" \ + ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80\n\t" \ + ".previous"); +#endif #endif /* dl-sysdep.h */ diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h b/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h index 466f0177c3..c59c8dbbdb 100644 --- a/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h +++ b/nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h @@ -16,52 +16,14 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#ifndef _DL_SYSDEP_H -#define _DL_SYSDEP_H 1 +#ifndef _LINUX_I686_DL_SYSDEP_H +#define _LINUX_I686_DL_SYSDEP_H 1 -/* This macro must be defined to either 0 or 1. +/* The i386 file does most of the work. */ +#include_next <dl-sysdep.h> - If 1, then an errno global variable hidden in ld.so will work right with - all the errno-using libc code compiled for ld.so, and there is never a - need to share the errno location with libc. This is appropriate only if - all the libc functions that ld.so uses are called without PLT and always - get the versions linked into ld.so rather than the libc ones. */ - -#ifdef IS_IN_rtld -# define RTLD_PRIVATE_ERRNO 1 -#else -# define RTLD_PRIVATE_ERRNO 0 -#endif - -/* Traditionally system calls have been made using int $0x80. A - second method was introduced which, if possible, will use the - sysenter/syscall instructions. To signal the presence and where to - find the code the kernel passes an AT_SYSINFO value in the - auxiliary vector to the application. */ -#define NEED_DL_SYSINFO 1 +/* Actually use the vDSO entry point for syscalls. + i386/dl-sysdep.h arranges to support it, but not use it. */ #define USE_DL_SYSINFO 1 -#if defined NEED_DL_SYSINFO && !defined __ASSEMBLER__ -extern void _dl_sysinfo_int80 (void) attribute_hidden; -# define DL_SYSINFO_DEFAULT (uintptr_t) _dl_sysinfo_int80 -# define DL_SYSINFO_IMPLEMENTATION \ - asm (".text\n\t" \ - ".type _dl_sysinfo_int80,@function\n\t" \ - ".hidden _dl_sysinfo_int80\n" \ - CFI_STARTPROC "\n" \ - "_dl_sysinfo_int80:\n\t" \ - "int $0x80;\n\t" \ - "ret;\n\t" \ - CFI_ENDPROC "\n" \ - ".size _dl_sysinfo_int80,.-_dl_sysinfo_int80\n\t" \ - ".previous"); -#endif - - -#ifndef __ASSEMBLER__ -/* Get version of the OS. */ -extern int _dl_discover_osversion (void) attribute_hidden; -# define HAVE_DL_DISCOVER_OSVERSION 1 -#endif - #endif /* dl-sysdep.h */ diff --git a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c index c33791ac2f..0efb72a56c 100644 --- a/nptl/sysdeps/unix/sysv/linux/lowlevellock.c +++ b/nptl/sysdeps/unix/sysv/linux/lowlevellock.c @@ -21,7 +21,7 @@ #include <sysdep.h> #include <lowlevellock.h> #include <sys/time.h> - +#include <atomic.h> void __lll_lock_wait_private (int *futex) diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h index b4b1fd4afd..f33f703346 100644 --- a/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h @@ -39,6 +39,8 @@ #define FUTEX_TRYLOCK_PI 8 #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 +#define FUTEX_WAIT_REQUEUE_PI 11 +#define FUTEX_CMP_REQUEUE_PI 12 #define FUTEX_PRIVATE_FLAG 128 #define FUTEX_CLOCK_REALTIME 256 @@ -149,6 +151,34 @@ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) +/* Priority Inheritance support. */ +#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \ + lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private) + +#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \ + mutex, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 5, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), mutex); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + #ifdef UP # define __lll_acq_instr "" diff --git a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h index a0163d6371..3dab05e057 100644 --- a/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h @@ -37,6 +37,8 @@ #define FUTEX_TRYLOCK_PI 8 #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 +#define FUTEX_WAIT_REQUEUE_PI 11 +#define FUTEX_CMP_REQUEUE_PI 12 #define FUTEX_PRIVATE_FLAG 128 #define FUTEX_CLOCK_REALTIME 256 @@ -141,6 +143,32 @@ INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ }) +/* Priority Inheritance support. */ +#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \ + lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private) + +#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \ + mutex, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \ + \ + INTERNAL_SYSCALL (futex, __err, 5, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), mutex); \ + }) + +#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + #define lll_compare_and_swap(futex, oldval, newval, operation) \ do { \ __typeof (futex) __futex = (futex); \ diff --git a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h index c88ec16434..2d7d9f82f6 100644 --- a/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h +++ b/nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h @@ -37,6 +37,8 @@ #define FUTEX_TRYLOCK_PI 8 #define FUTEX_WAIT_BITSET 9 #define FUTEX_WAKE_BITSET 10 +#define FUTEX_WAIT_REQUEUE_PI 11 +#define FUTEX_CMP_REQUEUE_PI 12 #define FUTEX_PRIVATE_FLAG 128 #define FUTEX_CLOCK_REALTIME 256 @@ -157,6 +159,34 @@ extern void __cpu_relax (void); }) #endif +/* Priority Inheritance support. */ +#define lll_futex_wait_requeue_pi(futexp, val, mutex, private) \ + lll_futex_timed_wait_requeue_pi (futexp, val, NULL, 0, mutex, private) + +#define lll_futex_timed_wait_requeue_pi(futexp, val, timespec, clockbit, \ + mutex, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + int __op = FUTEX_WAIT_REQUEUE_PI | clockbit; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 5, (futexp), \ + __lll_private_flag (__op, private), \ + (val), (timespec), mutex); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err) ? -__ret : __ret; \ + }) + +#define lll_futex_cmp_requeue_pi(futexp, nr_wake, nr_move, mutex, val, priv) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_CMP_REQUEUE_PI, priv),\ + (nr_wake), (nr_move), (mutex), (val)); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + static inline int __attribute__ ((always_inline)) __lll_trylock (int *futex) diff --git a/nptl/tst-barrier4.c b/nptl/tst-barrier4.c index 8b5b153219..2836fb341b 100644 --- a/nptl/tst-barrier4.c +++ b/nptl/tst-barrier4.c @@ -20,6 +20,7 @@ #include <errno.h> #include <pthread.h> #include <stdio.h> +#include <stdlib.h> static pthread_barrier_t b1; diff --git a/nptl/tst-cancel14.c b/nptl/tst-cancel14.c index fbaed4940f..ca9042d60a 100644 --- a/nptl/tst-cancel14.c +++ b/nptl/tst-cancel14.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/time.h> static pthread_barrier_t bar; diff --git a/nptl/tst-cancel15.c b/nptl/tst-cancel15.c index 0119cc761f..3f320ad00d 100644 --- a/nptl/tst-cancel15.c +++ b/nptl/tst-cancel15.c @@ -23,6 +23,7 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> +#include <sys/time.h> static pthread_barrier_t bar; diff --git a/nptl/tst-mutex9.c b/nptl/tst-mutex9.c index adb3b61f09..1d689bd7e4 100644 --- a/nptl/tst-mutex9.c +++ b/nptl/tst-mutex9.c @@ -18,10 +18,13 @@ #include <errno.h> #include <pthread.h> +#include <stdint.h> #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/mman.h> +#include <sys/time.h> #include <sys/wait.h> diff --git a/nptl/tst-oddstacklimit.c b/nptl/tst-oddstacklimit.c index 2c7783f56f..49754fe48c 100644 --- a/nptl/tst-oddstacklimit.c +++ b/nptl/tst-oddstacklimit.c @@ -21,6 +21,7 @@ #include <string.h> #include <sys/resource.h> #include <sys/wait.h> +#include <stdlib.h> /* This sets the stack resource limit to 1023kb, which is not a multiple of the page size since every architecture's page size is > 1k. */ diff --git a/nptl/tst-robust7.c b/nptl/tst-robust7.c index e64a4fc86d..ed1857c4ec 100644 --- a/nptl/tst-robust7.c +++ b/nptl/tst-robust7.c @@ -20,6 +20,7 @@ #include <pthread.h> #include <stdbool.h> #include <stdio.h> +#include <stdlib.h> static pthread_barrier_t b; diff --git a/nptl/tst-stackguard1.c b/nptl/tst-stackguard1.c index f0f707f43a..57a48ad292 100644 --- a/nptl/tst-stackguard1.c +++ b/nptl/tst-stackguard1.c @@ -24,6 +24,7 @@ #include <string.h> #include <sys/wait.h> #include <stackguard-macros.h> +#include <tls.h> #include <unistd.h> static const char *command; diff --git a/nptl/vars.c b/nptl/vars.c index 2bcd1f8e0a..45ca486143 100644 --- a/nptl/vars.c +++ b/nptl/vars.c @@ -20,13 +20,9 @@ #include <tls.h> #include <unistd.h> -/* Default stack size. */ -size_t __default_stacksize attribute_hidden -#ifdef SHARED -; -#else - = PTHREAD_STACK_MIN; -#endif +/* Default thread attributes for the case when the user does not + provide any. */ +struct pthread_attr __default_pthread_attr attribute_hidden; /* Flag whether the machine is SMP or not. */ int __is_smp attribute_hidden; |