[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[commits] r8462 - in /fsf/trunk/libc: ./ nptl/ nptl/sysdeps/pthread/ nscd/ posix/sys/ stdlib/ sunrpc/



Author: eglibc
Date: Sat May 16 15:35:06 2009
New Revision: 8462

Log:
Import glibc-mainline for 2009-05-16

Added:
    fsf/trunk/libc/nptl/libc-cleanup.c
    fsf/trunk/libc/nptl/nptl-init.c
Removed:
    fsf/trunk/libc/nptl/init.c
    fsf/trunk/libc/sunrpc/.gitignore
Modified:
    fsf/trunk/libc/ChangeLog
    fsf/trunk/libc/nptl/ChangeLog
    fsf/trunk/libc/nptl/Makefile
    fsf/trunk/libc/nptl/cancellation.c
    fsf/trunk/libc/nptl/libc-cancellation.c
    fsf/trunk/libc/nptl/sysdeps/pthread/librt-cancellation.c
    fsf/trunk/libc/nscd/nscd-client.h
    fsf/trunk/libc/nscd/nscd.h
    fsf/trunk/libc/nscd/nscd_helper.c
    fsf/trunk/libc/posix/sys/wait.h
    fsf/trunk/libc/stdlib/stdlib.h

Modified: fsf/trunk/libc/ChangeLog
==============================================================================
--- fsf/trunk/libc/ChangeLog (original)
+++ fsf/trunk/libc/ChangeLog Sat May 16 15:35:06 2009
@@ -1,8 +1,16 @@
+2009-05-16  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* posix/sys/wait.h: Fix typos.  Pretty printing.
+	* stdlib/stdlib.h: Likewise.  Correct comments.
+
+	[BZ #10159]
+	* stdlib/stdlib.h (__WAIT_INT): Match the definition in <sys/wait.h>.
+
+	* nscd/nscd_helper.c (__nscd_cache_search): Fix exit condition in last
+	patch.
+
 2009-05-15  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
-	* nscd/nscd.h: Move Definition for BLOCK_ALIGN_LOG, BLOCK_ALIGN, and
-	BLOCK_ALIGN_M1 to ...
-	* nscd/nscd-client.h: ...here.
 	* nscd/nscd_helper.c (__nscd_cache_search): Introduce loop counter.
 	Use it if we absolutely cannot reach any more correct list elements
 	because that many do not fit into the currently mapped database.

Modified: fsf/trunk/libc/nptl/ChangeLog
==============================================================================
--- fsf/trunk/libc/nptl/ChangeLog (original)
+++ fsf/trunk/libc/nptl/ChangeLog Sat May 16 15:35:06 2009
@@ -1,3 +1,18 @@
+2009-05-16  Ulrich Drepper  <drepper@xxxxxxxxxx>
+
+	* libc-cancellation.c: Move __libc_cleanup_routine to...
+	* libc-cleanup.c: ...here.  New file.
+	* Makefile (routines): Add libc-cleanup.
+
+	* cancellation.c (__pthread_disable_asynccancel): Remove unnecessary
+	test.
+	* libc-cancellation.c: Use <nptl/cancellation.c: to define the code.
+	* sysdeps/pthread/librt-cancellation.c: Likewise.
+
+	[BZ #9924]
+	* nptl-init.c: Renamed from init.c.
+	* Makefile: Change all occurences of init.c to nptl-init.c.
+
 2009-05-15  Ulrich Drepper  <drepper@xxxxxxxxxx>
 
 	* cancellation.c (__pthread_disable_asynccancel): Correct the bits

Modified: fsf/trunk/libc/nptl/Makefile
==============================================================================
--- fsf/trunk/libc/nptl/Makefile (original)
+++ fsf/trunk/libc/nptl/Makefile Sat May 16 15:35:06 2009
@@ -1,5 +1,4 @@
-# Copyright (C) 2002,2003,2004,2005,2006,2007,2008
-#	Free Software Foundation, Inc.
+# Copyright (C) 2002-2008,2009 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -28,10 +27,11 @@
 extra-libs-others := $(extra-libs)
 install-lib-ldscripts := libpthread.so
 
-routines = alloca_cutoff forward libc-lowlevellock libc-cancellation
+routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \
+	   libc-cleanup
 shared-only-routines = forward
 
-libpthread-routines = init vars events version \
+libpthread-routines = nptl-init vars events version \
 		      pthread_create pthread_exit pthread_detach \
 		      pthread_join pthread_tryjoin pthread_timedjoin \
 		      pthread_self pthread_equal pthread_yield \
@@ -139,8 +139,8 @@
 # we have to compile some files with exception handling enabled, some
 # even with asynchronous unwind tables.
 
-# init.c contains sigcancel_handler().
-CFLAGS-init.c = -fexceptions -fasynchronous-unwind-tables
+# nptl-init.c contains sigcancel_handler().
+CFLAGS-nptl-init.c = -fexceptions -fasynchronous-unwind-tables
 # The unwind code itself,
 CFLAGS-unwind.c = -fexceptions
 CFLAGS-unwind-forcedunwind.c = -fexceptions -fasynchronous-unwind-tables

Modified: fsf/trunk/libc/nptl/cancellation.c
==============================================================================
--- fsf/trunk/libc/nptl/cancellation.c (original)
+++ fsf/trunk/libc/nptl/cancellation.c Sat May 16 15:35:06 2009
@@ -78,9 +78,6 @@
     {
       newval = oldval & ~CANCELTYPE_BITMASK;
 
-      if (newval == oldval)
-	break;
-
       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
 					      oldval);
       if (__builtin_expect (curval == oldval, 1))

Modified: fsf/trunk/libc/nptl/libc-cancellation.c
==============================================================================
--- fsf/trunk/libc/nptl/libc-cancellation.c (original)
+++ fsf/trunk/libc/nptl/libc-cancellation.c Sat May 16 15:35:06 2009
@@ -17,113 +17,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <stdlib.h>
 #include "pthreadP.h"
-#include <atomic.h>
-#include <bits/libc-lock.h>
 
 
-#ifndef NOT_IN_libc
-
-/* The next two functions are similar to pthread_setcanceltype() but
-   more specialized for the use in the cancelable functions like write().
-   They do not need to check parameters etc.  */
-int
-attribute_hidden
-__libc_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval | CANCELTYPE_BITMASK;
-
-      if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
-	{
-	  /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
-	     stop right here.  */
-	  if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
-	    break;
-
-	  int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
-						  newval, oldval);
-	  if (__builtin_expect (curval != oldval, 0))
-	    {
-	      /* Somebody else modified the word, try again.  */
-	      oldval = curval;
-	      continue;
-	    }
-
-	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
-	  __do_cancel ();
-
-	  /* NOTREACHED */
-	}
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  return oldval;
-}
-
-
-void
-internal_function attribute_hidden
-__libc_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype & CANCELTYPE_BITMASK)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  int newval;
-
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      newval = oldval & ~CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  /* We cannot return when we are being canceled.  Upon return the
-     thread might be things which would have to be undone.  The
-     following loop should loop until the cancellation signal is
-     delivered.  */
-  while (__builtin_expect ((newval & (CANCELING_BITMASK | CANCELED_BITMASK))
-			   == CANCELING_BITMASK, 0))
-    {
-      lll_futex_wait (&self->cancelhandling, newval, LLL_PRIVATE);
-      newval = THREAD_GETMEM (self, cancelhandling);
-    }
-}
-
-
-void
-__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
-{
-  if (f->__do_it)
-    f->__cancel_routine (f->__cancel_arg);
-}
-
-#endif
+#define __pthread_enable_asynccancel __libc_enable_asynccancel
+#define __pthread_disable_asynccancel __libc_disable_asynccancel
+#include <nptl/cancellation.c>

Added: fsf/trunk/libc/nptl/libc-cleanup.c
==============================================================================
--- fsf/trunk/libc/nptl/libc-cleanup.c (added)
+++ fsf/trunk/libc/nptl/libc-cleanup.c Sat May 16 15:35:06 2009
@@ -1,0 +1,28 @@
+/* Copyright (C) 2002, 2003, 2005, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+
+
+void
+__libc_cleanup_routine (struct __pthread_cleanup_frame *f)
+{
+  if (f->__do_it)
+    f->__cancel_routine (f->__cancel_arg);
+}

Added: fsf/trunk/libc/nptl/nptl-init.c
==============================================================================
--- fsf/trunk/libc/nptl/nptl-init.c (added)
+++ fsf/trunk/libc/nptl/nptl-init.c Sat May 16 15:35:06 2009
@@ -1,0 +1,446 @@
+/* Copyright (C) 2002-2007, 2008, 2009 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#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 <shlib-compat.h>
+#include <smp.h>
+#include <lowlevellock.h>
+#include <kernel-features.h>
+
+
+/* Size and alignment of static TLS block.  */
+size_t __static_tls_size;
+size_t __static_tls_align_m1;
+
+#ifndef __ASSUME_SET_ROBUST_LIST
+/* Negative if we do not have the system call and we can use it.  */
+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
+/* Nonzero if we do not have 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
+
+/* Version of the library, used in libthread_db to detect mismatches.  */
+static const char nptl_version[] __attribute_used__ = VERSION;
+
+
+#ifndef SHARED
+extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign);
+#endif
+
+#ifdef SHARED
+static void nptl_freeres (void);
+
+
+static const struct pthread_functions pthread_functions =
+  {
+    .ptr_pthread_attr_destroy = __pthread_attr_destroy,
+# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
+    .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
+# endif
+    .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,
+# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_3_2)
+    .ptr___pthread_cond_broadcast_2_0 = __pthread_cond_broadcast_2_0,
+    .ptr___pthread_cond_destroy_2_0 = __pthread_cond_destroy_2_0,
+    .ptr___pthread_cond_init_2_0 = __pthread_cond_init_2_0,
+    .ptr___pthread_cond_signal_2_0 = __pthread_cond_signal_2_0,
+    .ptr___pthread_cond_wait_2_0 = __pthread_cond_wait_2_0,
+    .ptr___pthread_cond_timedwait_2_0 = __pthread_cond_timedwait_2_0,
+# endif
+    .ptr_pthread_equal = __pthread_equal,
+    .ptr___pthread_exit = __pthread_exit,
+    .ptr_pthread_getschedparam = __pthread_getschedparam,
+    .ptr_pthread_setschedparam = __pthread_setschedparam,
+    .ptr_pthread_mutex_destroy = INTUSE(__pthread_mutex_destroy),
+    .ptr_pthread_mutex_init = INTUSE(__pthread_mutex_init),
+    .ptr_pthread_mutex_lock = INTUSE(__pthread_mutex_lock),
+    .ptr_pthread_mutex_unlock = INTUSE(__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,
+    /* For now only the stack cache needs to be freed.  */
+    .ptr_freeres = nptl_freeres
+  };
+# define ptr_pthread_functions &pthread_functions
+#else
+# define ptr_pthread_functions NULL
+#endif
+
+
+#ifdef SHARED
+/* This function is called indirectly from the freeres code in libc.  */
+static void
+__libc_freeres_fn_section
+nptl_freeres (void)
+{
+  __unwind_freeres ();
+  __free_stacks (0);
+}
+#endif
+
+
+/* For asynchronous cancellation we use a signal.  This is the handler.  */
+static void
+sigcancel_handler (int sig, siginfo_t *si, void *ctx)
+{
+#ifdef __ASSUME_CORRECT_SI_PID
+  /* Determine the process ID.  It might be negative if the thread is
+     in the middle of a fork() call.  */
+  pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
+  if (__builtin_expect (pid < 0, 0))
+    pid = -pid;
+#endif
+
+  /* Safety check.  It would be possible to call this function for
+     other signals and send a signal from another process.  This is not
+     correct and might even be a security problem.  Try to catch as
+     many incorrect invocations as possible.  */
+  if (sig != SIGCANCEL
+#ifdef __ASSUME_CORRECT_SI_PID
+      /* Kernels before 2.5.75 stored the thread ID and not the process
+	 ID in si_pid so we skip this test.  */
+      || si->si_pid != pid
+#endif
+      || si->si_code != SI_TKILL)
+    return;
+
+  struct pthread *self = THREAD_SELF;
+
+  int oldval = THREAD_GETMEM (self, cancelhandling);
+  while (1)
+    {
+      /* We are canceled now.  When canceled by another thread this flag
+	 is already set but if the signal is directly send (internally or
+	 from another process) is has to be done here.  */
+      int newval = oldval | CANCELING_BITMASK | CANCELED_BITMASK;
+
+      if (oldval == newval || (oldval & EXITING_BITMASK) != 0)
+	/* Already canceled or exiting.  */
+	break;
+
+      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
+					      oldval);
+      if (curval == oldval)
+	{
+	  /* Set the return value.  */
+	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
+
+	  /* Make sure asynchronous cancellation is still enabled.  */
+	  if ((newval & CANCELTYPE_BITMASK) != 0)
+	    /* Run the registered destructors and terminate the thread.  */
+	    __do_cancel ();
+
+	  break;
+	}
+
+      oldval = curval;
+    }
+}
+
+
+struct xid_command *__xidcmd attribute_hidden;
+
+/* For asynchronous cancellation we use a signal.  This is the handler.  */
+static void
+sighandler_setxid (int sig, siginfo_t *si, void *ctx)
+{
+#ifdef __ASSUME_CORRECT_SI_PID
+  /* Determine the process ID.  It might be negative if the thread is
+     in the middle of a fork() call.  */
+  pid_t pid = THREAD_GETMEM (THREAD_SELF, pid);
+  if (__builtin_expect (pid < 0, 0))
+    pid = -pid;
+#endif
+
+  /* Safety check.  It would be possible to call this function for
+     other signals and send a signal from another process.  This is not
+     correct and might even be a security problem.  Try to catch as
+     many incorrect invocations as possible.  */
+  if (sig != SIGSETXID
+#ifdef __ASSUME_CORRECT_SI_PID
+      /* Kernels before 2.5.75 stored the thread ID and not the process
+	 ID in si_pid so we skip this test.  */
+      || si->si_pid != 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, LLL_PRIVATE);
+
+  /* Reset the SETXID flag.  */
+  struct pthread *self = THREAD_SELF;
+  int flags = THREAD_GETMEM (self, cancelhandling);
+  THREAD_SETMEM (self, cancelhandling, flags & ~SETXID_BITMASK);
+
+  /* And release the futex.  */
+  self->setxid_futex = 1;
+  lll_futex_wake (&self->setxid_futex, 1, LLL_PRIVATE);
+}
+
+
+/* When using __thread for this, we do it in libc so as not
+   to give libpthread its own TLS segment just for this.  */
+extern void **__libc_dl_error_tsd (void) __attribute__ ((const));
+
+
+/* This can be set by the debugger before initialization is complete.  */
+static bool __nptl_initial_report_events __attribute_used__;
+
+void
+__pthread_initialize_minimal_internal (void)
+{
+#ifndef SHARED
+  /* Unlike in the dynamically linked case the dynamic linker has not
+     taken care of initializing the TLS data structures.  */
+  __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN);
+
+  /* We must prevent gcc from being clever and move any of the
+     following code ahead of the __libc_setup_tls call.  This function
+     will initialize the thread register which is subsequently
+     used.  */
+  __asm __volatile ("");
+#endif
+
+  /* Minimal initialization of the thread descriptor.  */
+  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
+
+  /* Initialize the robust mutex data.  */
+#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
+  /* Private futexes are always used (at least internally) so that
+     doing the test once this early is beneficial.  */
+  {
+    int word = 0;
+    word = INTERNAL_SYSCALL (futex, err, 3, &word,
+			    FUTEX_WAKE | FUTEX_PRIVATE_FLAG, 1);
+    if (!INTERNAL_SYSCALL_ERROR_P (word, err))
+      THREAD_SETMEM (pd, header.private_futex, FUTEX_PRIVATE_FLAG);
+  }
+
+  /* Private futexes have been introduced earlier than the
+     FUTEX_CLOCK_REALTIME flag.  We don't have to run the test if we
+     know the former are not supported.  This also means we know the
+     kernel will return ENOSYS for unknown operations.  */
+  if (THREAD_GETMEM (pd, header.private_futex) != 0)
+#endif
+#ifndef __ASSUME_FUTEX_CLOCK_REALTIME
+    {
+      int word = 0;
+      /* NB: the syscall actually takes six parameters.  The last is the
+	 bit mask.  But since we will not actually wait at all the value
+	 is irrelevant.  Given that passing six parameters is difficult
+	 on some architectures we just pass whatever random value the
+	 calling convention calls for to the kernel.  It causes no harm.  */
+      word = INTERNAL_SYSCALL (futex, err, 5, &word,
+			       FUTEX_WAIT_BITSET | FUTEX_CLOCK_REALTIME
+			       | FUTEX_PRIVATE_FLAG, 1, NULL, 0);
+      assert (INTERNAL_SYSCALL_ERROR_P (word, err));
+      if (INTERNAL_SYSCALL_ERRNO (word, err) != ENOSYS)
+	__set_futex_clock_realtime ();
+    }
+#endif
+
+  /* Set initial thread's stack block from 0 up to __libc_stack_end.
+     It will be bigger than it actually is, but for unwind.c/pt-longjmp.c
+     purposes this is good enough.  */
+  THREAD_SETMEM (pd, stackblock_size, (size_t) __libc_stack_end);
+
+  /* Initialize the list of all running threads with the main thread.  */
+  INIT_LIST_HEAD (&__stack_user);
+  list_add (&pd->list, &__stack_user);
+
+  /* Before initializing __stack_user, the debugger could not find us and
+     had to set __nptl_initial_report_events.  Propagate its setting.  */
+  THREAD_SETMEM (pd, report_events, __nptl_initial_report_events);
+
+  /* Install the cancellation signal handler.  If for some reason we
+     cannot install the handler we do not abort.  Maybe we should, but
+     it is only asynchronous cancellation which is affected.  */
+  struct sigaction sa;
+  sa.sa_sigaction = sigcancel_handler;
+  sa.sa_flags = SA_SIGINFO;
+  __sigemptyset (&sa.sa_mask);
+
+  (void) __libc_sigaction (SIGCANCEL, &sa, NULL);
+
+  /* Install the handle to change the threads' uid/gid.  */
+  sa.sa_sigaction = sighandler_setxid;
+  sa.sa_flags = SA_SIGINFO | SA_RESTART;
+
+  (void) __libc_sigaction (SIGSETXID, &sa, NULL);
+
+  /* The parent process might have left the signals blocked.  Just in
+     case, unblock it.  We reuse the signal mask in the sigaction
+     structure.  It is already cleared.  */
+  __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);
+
+  /* Get the size of the static and alignment requirements for the TLS
+     block.  */
+  size_t static_tls_align;
+  _dl_get_tls_static_info (&__static_tls_size, &static_tls_align);
+
+  /* Make sure the size takes all the alignments into account.  */
+  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);
+
+  /* Determine the default allowed stack size.  This is the size used
+     in case the user does not specify one.  */
+  struct rlimit limit;
+  if (getrlimit (RLIMIT_STACK, &limit) != 0
+      || limit.rlim_cur == RLIM_INFINITY)
+    /* The system limit is not usable.  Use an architecture-specific
+       default.  */
+    limit.rlim_cur = ARCH_STACK_DEFAULT_SIZE;
+  else if (limit.rlim_cur < PTHREAD_STACK_MIN)
+    /* The system limit is unusably small.
+       Use the minimal size acceptable.  */
+    limit.rlim_cur = PTHREAD_STACK_MIN;
+
+  /* Make sure it meets the minimum size that allocate_stack
+     (allocatestack.c) will demand, which depends on the page size.  */
+  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;
+
+  /* Round the resource limit up to page size.  */
+  limit.rlim_cur = (limit.rlim_cur + pagesz - 1) & -pagesz;
+  __default_stacksize = limit.rlim_cur;
+
+#ifdef SHARED
+  /* Transfer the old value from the dynamic linker's internal location.  */
+  *__libc_dl_error_tsd () = *(*GL(dl_error_catch_tsd)) ();
+  GL(dl_error_catch_tsd) = &__libc_dl_error_tsd;
+
+  /* Make __rtld_lock_{,un}lock_recursive use pthread_mutex_{,un}lock,
+     keep the lock count from the ld.so implementation.  */
+  GL(dl_rtld_lock_recursive) = (void *) INTUSE (__pthread_mutex_lock);
+  GL(dl_rtld_unlock_recursive) = (void *) INTUSE (__pthread_mutex_unlock);
+  unsigned int rtld_lock_count = GL(dl_load_lock).mutex.__data.__count;
+  GL(dl_load_lock).mutex.__data.__count = 0;
+  while (rtld_lock_count-- > 0)
+    INTUSE (__pthread_mutex_lock) (&GL(dl_load_lock).mutex);
+
+  GL(dl_make_stack_executable_hook) = &__make_stacks_executable;
+#endif
+
+  GL(dl_init_static_tls) = &__pthread_init_static_tls;
+
+  GL(dl_wait_lookup_done) = &__wait_lookup_done;
+
+  /* Register the fork generation counter with the libc.  */
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+  __libc_multiple_threads_ptr =
+#endif
+    __libc_pthread_init (&__fork_generation, __reclaim_stacks,
+			 ptr_pthread_functions);
+
+  /* Determine whether the machine is SMP or not.  */
+  __is_smp = is_smp_system ();
+}
+strong_alias (__pthread_initialize_minimal_internal,
+	      __pthread_initialize_minimal)

Modified: fsf/trunk/libc/nptl/sysdeps/pthread/librt-cancellation.c
==============================================================================
--- fsf/trunk/libc/nptl/sysdeps/pthread/librt-cancellation.c (original)
+++ fsf/trunk/libc/nptl/sysdeps/pthread/librt-cancellation.c Sat May 16 15:35:06 2009
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2009 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@xxxxxxxxxx>, 2002.
 
@@ -17,92 +17,9 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <setjmp.h>
-#include <signal.h>
-#include <stdlib.h>
 #include "pthreadP.h"
-#include "atomic.h"
 
 
-#ifdef IS_IN_librt
-/* The next two functions are similar to pthread_setcanceltype() but
-   more specialized for the use in the cancelable functions like write().
-   They do not need to check parameters etc.  */
-int
-attribute_hidden
-__librt_enable_asynccancel (void)
-{
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval | CANCELTYPE_BITMASK;
-
-      if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
-	{
-	  /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
-	     stop right here.  */
-	  if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
-	    break;
-
-	  int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
-						  newval, oldval);
-	  if (__builtin_expect (curval != oldval, 0))
-	    {
-	      /* Somebody else modified the word, try again.  */
-	      oldval = curval;
-	      continue;
-	    }
-
-	  THREAD_SETMEM (self, result, PTHREAD_CANCELED);
-
-	  __do_cancel ();
-
-	  /* NOTREACHED */
-	}
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-
-  return oldval;
-}
-
-
-void
-internal_function attribute_hidden
-__librt_disable_asynccancel (int oldtype)
-{
-  /* If asynchronous cancellation was enabled before we do not have
-     anything to do.  */
-  if (oldtype & CANCELTYPE_BITMASK)
-    return;
-
-  struct pthread *self = THREAD_SELF;
-  int oldval = THREAD_GETMEM (self, cancelhandling);
-
-  while (1)
-    {
-      int newval = oldval & ~CANCELTYPE_BITMASK;
-
-      if (newval == oldval)
-	break;
-
-      int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
-					      oldval);
-      if (__builtin_expect (curval == oldval, 1))
-	break;
-
-      /* Prepare the next round.  */
-      oldval = curval;
-    }
-}
-
-
-#endif
+#define __pthread_enable_asynccancel __librt_enable_asynccancel
+#define __pthread_disable_asynccancel __librt_disable_asynccancel
+#include <nptl/cancellation.c>

Modified: fsf/trunk/libc/nscd/nscd-client.h
==============================================================================
--- fsf/trunk/libc/nscd/nscd-client.h (original)
+++ fsf/trunk/libc/nscd/nscd-client.h Sat May 16 15:35:06 2009
@@ -46,11 +46,6 @@
 
 /* Maximum allowed length for the key.  */
 #define MAXKEYLEN 1024
-
-/* Maximum alignment requirement we will encounter.  */
-#define BLOCK_ALIGN_LOG 3
-#define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
-#define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
 
 
 /* Available services.  */

Modified: fsf/trunk/libc/nscd/nscd.h
==============================================================================
--- fsf/trunk/libc/nscd/nscd.h (original)
+++ fsf/trunk/libc/nscd/nscd.h Sat May 16 15:35:06 2009
@@ -110,6 +110,11 @@
 
 /* Path used when not using persistent storage.  */
 #define _PATH_NSCD_XYZ_DB_TMP	"/var/run/nscd/dbXXXXXX"
+
+/* Maximum alignment requirement we will encounter.  */
+#define BLOCK_ALIGN_LOG 3
+#define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
+#define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
 
 /* Default value for the maximum size of the database files.  */
 #define DEFAULT_MAX_DB_SIZE	(32 * 1024 * 1024)

Modified: fsf/trunk/libc/nscd/nscd_helper.c
==============================================================================
--- fsf/trunk/libc/nscd/nscd_helper.c (original)
+++ fsf/trunk/libc/nscd/nscd_helper.c Sat May 16 15:35:06 2009
@@ -528,7 +528,7 @@
       work = atomic_forced_read (here->next);
       /* Prevent endless loops.  This should never happen but perhaps
 	 the database got corrupted, accidentally or deliberately.  */
-      if (work == trail || loop_cnt-- > 0)
+      if (work == trail || loop_cnt-- == 0)
 	break;
       if (tick)
 	{

Modified: fsf/trunk/libc/posix/sys/wait.h
==============================================================================
--- fsf/trunk/libc/posix/sys/wait.h (original)
+++ fsf/trunk/libc/posix/sys/wait.h Sat May 16 15:35:06 2009
@@ -1,5 +1,5 @@
-/* Copyright (C) 1991-1994,1996-2001,2003,2004,2005,2007
-	Free Software Foundation, Inc.
+/* Copyright (C) 1991-1994,1996-2001,2003,2004,2005,2007,2009
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
    The GNU C Library is free software; you can redistribute it and/or
@@ -51,7 +51,7 @@
 #  endif
 
 /* This is the type of the argument to `wait'.  The funky union
-   causes redeclarations with ether `int *' or `union wait *' to be
+   causes redeclarations with either `int *' or `union wait *' to be
    allowed without complaint.  __WAIT_STATUS_DEFN is the type used in
    the actual function definitions.  */
 
@@ -79,22 +79,22 @@
 /* This will define all the `__W*' macros.  */
 # include <bits/waitstatus.h>
 
-# define WEXITSTATUS(status)	__WEXITSTATUS(__WAIT_INT(status))
-# define WTERMSIG(status)	__WTERMSIG(__WAIT_INT(status))
-# define WSTOPSIG(status)	__WSTOPSIG(__WAIT_INT(status))
-# define WIFEXITED(status)	__WIFEXITED(__WAIT_INT(status))
-# define WIFSIGNALED(status)	__WIFSIGNALED(__WAIT_INT(status))
-# define WIFSTOPPED(status)	__WIFSTOPPED(__WAIT_INT(status))
+# define WEXITSTATUS(status)	__WEXITSTATUS (__WAIT_INT (status))
+# define WTERMSIG(status)	__WTERMSIG (__WAIT_INT (status))
+# define WSTOPSIG(status)	__WSTOPSIG (__WAIT_INT (status))
+# define WIFEXITED(status)	__WIFEXITED (__WAIT_INT (status))
+# define WIFSIGNALED(status)	__WIFSIGNALED (__WAIT_INT (status))
+# define WIFSTOPPED(status)	__WIFSTOPPED (__WAIT_INT (status))
 # ifdef __WIFCONTINUED
-#  define WIFCONTINUED(status)	__WIFCONTINUED(__WAIT_INT(status))
+#  define WIFCONTINUED(status)	__WIFCONTINUED (__WAIT_INT (status))
 # endif
 #endif	/* <stdlib.h> not included.  */
 
 #ifdef	__USE_BSD
 # define WCOREFLAG		__WCOREFLAG
-# define WCOREDUMP(status)	__WCOREDUMP(__WAIT_INT(status))
-# define W_EXITCODE(ret, sig)	__W_EXITCODE(ret, sig)
-# define W_STOPCODE(sig)	__W_STOPCODE(sig)
+# define WCOREDUMP(status)	__WCOREDUMP (__WAIT_INT (status))
+# define W_EXITCODE(ret, sig)	__W_EXITCODE (ret, sig)
+# define W_STOPCODE(sig)	__W_STOPCODE (sig)
 #endif
 
 /* The following values are used by the `waitid' function.  */

Modified: fsf/trunk/libc/stdlib/stdlib.h
==============================================================================
--- fsf/trunk/libc/stdlib/stdlib.h (original)
+++ fsf/trunk/libc/stdlib/stdlib.h Sat May 16 15:35:06 2009
@@ -48,15 +48,15 @@
    as well as POSIX.1 use of `int' for the status word.  */
 
 #  if defined __GNUC__ && !defined __cplusplus
-#   define __WAIT_INT(status)						      \
-  (__extension__ ({ union { __typeof(status) __in; int __i; } __u;	      \
-		    __u.__in = (status); __u.__i; }))
+#   define __WAIT_INT(status) \
+  (__extension__ (((union { __typeof(status) __in; int __i; }) \
+                   { .__in = (status) }).__i))
 #  else
 #   define __WAIT_INT(status)	(*(int *) &(status))
 #  endif
 
 /* This is the type of the argument to `wait'.  The funky union
-   causes redeclarations with ether `int *' or `union wait *' to be
+   causes redeclarations with either `int *' or `union wait *' to be
    allowed without complaint.  __WAIT_STATUS_DEFN is the type used in
    the actual function definitions.  */
 
@@ -82,14 +82,14 @@
 # endif /* Use BSD.  */
 
 /* Define the macros <sys/wait.h> also would define this way.  */
-# define WEXITSTATUS(status)	__WEXITSTATUS(__WAIT_INT(status))
-# define WTERMSIG(status)	__WTERMSIG(__WAIT_INT(status))
-# define WSTOPSIG(status)	__WSTOPSIG(__WAIT_INT(status))
-# define WIFEXITED(status)	__WIFEXITED(__WAIT_INT(status))
-# define WIFSIGNALED(status)	__WIFSIGNALED(__WAIT_INT(status))
-# define WIFSTOPPED(status)	__WIFSTOPPED(__WAIT_INT(status))
+# define WEXITSTATUS(status)	__WEXITSTATUS (__WAIT_INT (status))
+# define WTERMSIG(status)	__WTERMSIG (__WAIT_INT (status))
+# define WSTOPSIG(status)	__WSTOPSIG (__WAIT_INT (status))
+# define WIFEXITED(status)	__WIFEXITED (__WAIT_INT (status))
+# define WIFSIGNALED(status)	__WIFSIGNALED (__WAIT_INT (status))
+# define WIFSTOPPED(status)	__WIFSTOPPED (__WAIT_INT (status))
 # ifdef __WIFCONTINUED
-#  define WIFCONTINUED(status)	__WIFCONTINUED(__WAIT_INT(status))
+#  define WIFCONTINUED(status)	__WIFCONTINUED (__WAIT_INT (status))
 # endif
 #endif	/* X/Open and <sys/wait.h> not included.  */
 
@@ -222,14 +222,14 @@
 #ifdef __USE_GNU
 /* The concept of one static locale per category is not very well
    thought out.  Many applications will need to process its data using
-   information from several different locales.  Another application is
+   information from several different locales.  Another problem is
    the implementation of the internationalization handling in the
-   upcoming ISO C++ standard library.  To support this another set of
-   the functions using locale data exist which have an additional
+   ISO C++ standard library.  To support this another set of
+   the functions using locale data exist which take an additional
    argument.
 
-   Attention: all these functions are *not* standardized in any form.
-   This is a proof-of-concept implementation.  */
+   Attention: even though several *_l interfaces are part of POSIX:2008,
+   these are not.  */
 
 /* Structure for reentrant locale using functions.  This is an
    (almost) opaque type for the user level programs.  */