summaryrefslogtreecommitdiff
path: root/nptl
diff options
context:
space:
mode:
Diffstat (limited to 'nptl')
-rw-r--r--nptl/ChangeLog120
-rw-r--r--nptl/Makeconfig1
-rw-r--r--nptl/allocatestack.c2
-rw-r--r--nptl/nptl-init.c3
-rw-r--r--nptl/pthreadP.h16
-rw-r--r--nptl/pthread_attr_getstacksize.c2
-rw-r--r--nptl/pthread_barrier_init.c4
-rw-r--r--nptl/pthread_cond_broadcast.c45
-rw-r--r--nptl/pthread_cond_signal.c33
-rw-r--r--nptl/pthread_cond_timedwait.c59
-rw-r--r--nptl/pthread_cond_wait.c57
-rw-r--r--nptl/pthread_create.c14
-rw-r--r--nptl/pthread_mutex_init.c5
-rw-r--r--nptl/pthread_rwlock_init.c4
-rw-r--r--nptl/sysdeps/pthread/bits/libc-lockP.h45
-rw-r--r--nptl/sysdeps/pthread/tst-timer.c1
-rw-r--r--nptl/sysdeps/unix/sysv/linux/fork.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/dl-sysdep.h31
-rw-r--r--nptl/sysdeps/unix/sysv/linux/i386/i686/dl-sysdep.h50
-rw-r--r--nptl/sysdeps/unix/sysv/linux/lowlevellock.c2
-rw-r--r--nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h30
-rw-r--r--nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h28
-rw-r--r--nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h30
-rw-r--r--nptl/tst-barrier4.c1
-rw-r--r--nptl/tst-cancel14.c1
-rw-r--r--nptl/tst-cancel15.c1
-rw-r--r--nptl/tst-mutex9.c3
-rw-r--r--nptl/tst-oddstacklimit.c1
-rw-r--r--nptl/tst-robust7.c1
-rw-r--r--nptl/tst-stackguard1.c1
-rw-r--r--nptl/vars.c10
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;