]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
* sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Use
authorDaniel Jacobowitz <dan@codesourcery.com>
Tue, 10 Jul 2007 13:35:30 +0000 (13:35 +0000)
committerDaniel Jacobowitz <dan@codesourcery.com>
Tue, 10 Jul 2007 13:35:30 +0000 (13:35 +0000)
lll_private_futex_wake.
* sysdeps/unix/sysv/linux/arm/check_pf.c: Update from generic version.
* sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c
(pthread_cancel_init): Add noinline and barriers.
* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c
(__lll_timedlock_wait): Update call to lll_futex_timed_wait.
(__lll_timedwait_tid): Likewise.
* sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h (LLL_PRIVATE,
LLL_SHARED): Define.
(lll_futex_wait): Use lll_futex_timed_wait.
(lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Take a
PRIVATE argument.
(lll_private_futex_wait, lll_private_futex_timed_wait,
lll_private_futex_wake): New.
(lll_robust_mutex_dead,  __lll_mutex_lock, __lll_mutex_cond_lock,
__lll_mutex_unlock, __lll_robust_mutex_unlock,
__lll_mutex_unlock_force, lll_wait_tid): Update calls.
* sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c (clear_once_control,
__pthread_once): Use private futexes.
* sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
(pthread_cancel_init): Add noinline and barriers.

* sysdeps/unix/sysv/aix/bits/fcntl.h,
sysdeps/unix/sysv/linux/am33/bits/fcntl.h,
sysdeps/unix/sysv/linux/arm/bits/fcntl.h,
sysdeps/unix/sysv/linux/cris/bits/fcntl.h,
sysdeps/unix/sysv/linux/m68k/bits/fcntl.h,
sysdeps/unix/sysv/linux/mips/bits/fcntl.h: Comment fix.

* sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h (SEM_VALUE_MAX):
Delete.
* sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h (SEM_VALUE_MAX):
Delete.

21 files changed:
ChangeLog.aix
ChangeLog.am33
ChangeLog.arm
ChangeLog.cris
ChangeLog.m68k
ChangeLog.mips
sysdeps/arm/nptl/tls.h
sysdeps/unix/sysv/aix/bits/fcntl.h
sysdeps/unix/sysv/linux/am33/bits/fcntl.h
sysdeps/unix/sysv/linux/arm/bits/fcntl.h
sysdeps/unix/sysv/linux/arm/check_pf.c
sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c
sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h
sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c
sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h
sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c
sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
sysdeps/unix/sysv/linux/cris/bits/fcntl.h
sysdeps/unix/sysv/linux/m68k/bits/fcntl.h
sysdeps/unix/sysv/linux/mips/bits/fcntl.h
sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h

index 5305d338db546d72b90dece90b42a0896ed214f3..3e3e4df3079270b8ba4ffc6095a1a5a263b3ec15 100644 (file)
@@ -1,3 +1,7 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/unix/sysv/aix/bits/fcntl.h: Comment fix.
+
 2005-12-27  Roland McGrath  <roland@redhat.com>
 
        * sysdeps/unix/sysv/aix/bits/setjmp.h (_JMPBUF_UNWINDS): Take third
index f794cc55dcf43ba88591399230fff9101ebe4689..c10f8d08e464594faee4282af168e56f5577b42d 100644 (file)
@@ -1,3 +1,7 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/am33/bits/fcntl.h: Comment fix.
+
 2006-01-12  Roland McGrath  <roland@redhat.com>
 
        * sysdeps/am33/jmpbuf-unwind.h: Include <jmpbuf-offsets.h>.
index 39e14dca9524a431c28964e6ba2a4c8639e6a56f..5a24c54ff9ac91815501050b3c72d124cedc0c7a 100644 (file)
@@ -1,3 +1,33 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_RESET_FLAG): Use
+       lll_private_futex_wake.
+       * sysdeps/unix/sysv/linux/arm/check_pf.c: Update from generic version.
+       * sysdeps/unix/sysv/linux/arm/eabi/nptl/unwind-forcedunwind.c
+       (pthread_cancel_init): Add noinline and barriers.
+       * sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.c
+       (__lll_timedlock_wait): Update call to lll_futex_timed_wait.
+       (__lll_timedwait_tid): Likewise.
+       * sysdeps/unix/sysv/linux/arm/nptl/lowlevellock.h (LLL_PRIVATE,
+       LLL_SHARED): Define.
+       (lll_futex_wait): Use lll_futex_timed_wait.
+       (lll_futex_timed_wait, lll_futex_wake, lll_futex_wake_unlock): Take a
+       PRIVATE argument.
+       (lll_private_futex_wait, lll_private_futex_timed_wait,
+       lll_private_futex_wake): New.
+       (lll_robust_mutex_dead,  __lll_mutex_lock, __lll_mutex_cond_lock,
+       __lll_mutex_unlock, __lll_robust_mutex_unlock,
+       __lll_mutex_unlock_force, lll_wait_tid): Update calls.
+       * sysdeps/unix/sysv/linux/arm/nptl/pthread_once.c (clear_once_control,
+       __pthread_once): Use private futexes.
+       * sysdeps/unix/sysv/linux/arm/nptl/unwind-forcedunwind.c
+       (pthread_cancel_init): Add noinline and barriers.
+
+       * sysdeps/unix/sysv/linux/arm/bits/fcntl.h: Comment fix.
+
+       * sysdeps/unix/sysv/linux/arm/nptl/bits/semaphore.h (SEM_VALUE_MAX):
+       Delete.
+
 2007-06-06  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * sysdeps/arm/nptl/tls.h (THREAD_GSCOPE_FLAG_UNUSED,
index af91a1d4203fd923291175a087730388192fff9c..746c89cbf512af4383c9f87c7ac0745c62db39f1 100644 (file)
@@ -1,3 +1,7 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/cris/bits/fcntl.h: Comment fix.
+
 2005-12-27  Roland McGrath  <roland@redhat.com>
 
        * sysdeps/cris/bits/setjmp.h (_JMPBUF_UNWINDS): Take third argument
index 51f6dfa022b23bbf9a1a5af9578e4221a12b5ae4..fb591ad11d61e0eb4dc6b0ccb565b90047a1ecbf 100644 (file)
@@ -1,3 +1,7 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/m68k/bits/fcntl.h: Comment fix.
+
 2006-11-28  Andreas Schwab  <schwab@suse.de>
 
        * sysdeps/unix/sysv/linux/m68k/sysdep.h (DOARGS_6, _DOARGS_6)
index 346237f346241c75f5eec407efdfe35f2155d849..3ea63cd8c7f465b32e87b4dc649ba927cd9dc16d 100644 (file)
@@ -1,3 +1,10 @@
+2007-07-10  Daniel Jacobowitz  <dan@codesourcery.com>
+
+       * sysdeps/unix/sysv/linux/mips/bits/fcntl.h: Comment fix.
+
+       * sysdeps/unix/sysv/linux/mips/nptl/bits/semaphore.h (SEM_VALUE_MAX):
+       Delete.
+
 2007-06-07  Daniel Jacobowitz  <dan@codesourcery.com>
 
        * sysdeps/unix/sysv/linux/mips/mips64/n32/sysdep.h (ARGIFY): New.
index ae2aecc42bcb1910a2fce197ae35745c0bf6458a..e80b6b8d0674ac5e90b190fdee55fc3e0edf07f6 100644 (file)
@@ -142,7 +142,7 @@ typedef struct
        = atomic_exchange_rel (&THREAD_SELF->header.gscope_flag,             \
                               THREAD_GSCOPE_FLAG_UNUSED);                   \
       if (__res == THREAD_GSCOPE_FLAG_WAIT)                                 \
-       lll_futex_wake (&THREAD_SELF->header.gscope_flag, 1);                \
+       lll_private_futex_wake (&THREAD_SELF->header.gscope_flag, 1);        \
     }                                                                       \
   while (0)
 #define THREAD_GSCOPE_SET_FLAG() \
index c65b8beeb4bfcace1085afdfc57e9d83ec4abc51..d53c0f7d9bd38e88f94d14b2ce2277e56996cdb9 100644 (file)
@@ -79,7 +79,7 @@
 # define F_GETOWN      9       /* Set owner of socket (receiver of SIGIO).  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index 4c276c5485292689a91d7cee9e502dd5552ddd75..f2c88fad101714dfb12922cee3944a017f881bff 100644 (file)
@@ -94,7 +94,7 @@
 # define F_NOTIFY      1026    /* Request notfications on a directory.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index 7c7b7c202782feb0cc7bc21c73c6247e1c7ff89f..59539e17587bfce59d2d25a16b0d075f8a232d51 100644 (file)
@@ -98,7 +98,7 @@
 # define F_NOTIFY      1026    /* Request notfications on a directory.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index ee13d8019c69de7e81d7f5cab20f5a8a58dab48c..dfca75d374c1995ef52b29497bab16accaf657be 100644 (file)
@@ -1,5 +1,5 @@
-/* Determine protocol families for which interfaces exist.  ARM Linux version.
-   Copyright (C) 2003, 2006 Free Software Foundation, Inc.
+/* Determine protocol families for which interfaces exist.  Linux version.
+   Copyright (C) 2003, 2006, 2007 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
@@ -69,17 +69,38 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
   memset (&nladdr, '\0', sizeof (nladdr));
   nladdr.nl_family = AF_NETLINK;
 
+#ifdef PAGE_SIZE
+  /* Help the compiler optimize out the malloc call if PAGE_SIZE
+     is constant and smaller or equal to PTHREAD_STACK_MIN/4.  */
+  const size_t buf_size = PAGE_SIZE;
+#else
+  const size_t buf_size = __getpagesize ();
+#endif
+  bool use_malloc = false;
+  char *buf;
+
+  if (__libc_use_alloca (buf_size))
+    buf = alloca (buf_size);
+  else
+    {
+      buf = malloc (buf_size);
+      if (buf != NULL)
+       use_malloc = true;
+      else
+       goto out_fail;
+    }
+
+  struct iovec iov = { buf, buf_size };
+
   if (TEMP_FAILURE_RETRY (__sendto (fd, (void *) &req, sizeof (req), 0,
                                    (struct sockaddr *) &nladdr,
                                    sizeof (nladdr))) < 0)
-    return -1;
+    goto out_fail;
 
   *seen_ipv4 = false;
   *seen_ipv6 = false;
 
   bool done = false;
-  char buf[4096];
-  struct iovec iov = { buf, sizeof (buf) };
   struct in6ailist
   {
     struct in6addrinfo info;
@@ -99,10 +120,10 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
 
       ssize_t read_len = TEMP_FAILURE_RETRY (__recvmsg (fd, &msg, 0));
       if (read_len < 0)
-       return -1;
+       goto out_fail;
 
       if (msg.msg_flags & MSG_TRUNC)
-       return -1;
+       goto out_fail;
 
       struct nlmsghdr *nlmh;
       for (nlmh = (struct nlmsghdr *) buf;
@@ -116,40 +137,72 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
          if (nlmh->nlmsg_type == RTM_NEWADDR)
            {
              struct ifaddrmsg *ifam = (struct ifaddrmsg *) NLMSG_DATA (nlmh);
+             struct rtattr *rta = IFA_RTA (ifam);
+             size_t len = nlmh->nlmsg_len - NLMSG_LENGTH (sizeof (*ifam));
 
              switch (ifam->ifa_family)
                {
+                 const void *local;
+                 const void *address;
+
                case AF_INET:
-                 *seen_ipv4 = true;
+                 local = NULL;
+                 address = NULL;
+                 while (RTA_OK (rta, len))
+                   {
+                     switch (rta->rta_type)
+                       {
+                       case IFA_LOCAL:
+                         local = RTA_DATA (rta);
+                         break;
+
+                       case IFA_ADDRESS:
+                         address = RTA_DATA (rta);
+                         goto out_v4;
+                       }
+
+                     rta = RTA_NEXT (rta, len);
+                   }
+
+                 if (local != NULL)
+                   {
+                   out_v4:
+                     if (*(const in_addr_t *) (address ?: local)
+                         != htonl (INADDR_LOOPBACK))
+                       *seen_ipv4 = true;
+                   }
                  break;
+
                case AF_INET6:
-                 *seen_ipv6 = true;
+                 local = NULL;
+                 address = NULL;
+                 while (RTA_OK (rta, len))
+                   {
+                     switch (rta->rta_type)
+                       {
+                       case IFA_LOCAL:
+                         local = RTA_DATA (rta);
+                         break;
+
+                       case IFA_ADDRESS:
+                         address = RTA_DATA (rta);
+                         goto out_v6;
+                       }
+
+                     rta = RTA_NEXT (rta, len);
+                   }
+
+                 if (local != NULL)
+                   {
+                   out_v6:
+                     if (!IN6_IS_ADDR_LOOPBACK (address ?: local))
+                       *seen_ipv6 = true;
+                   }
 
                  if (ifam->ifa_flags & (IFA_F_DEPRECATED
                                         | IFA_F_TEMPORARY
                                         | IFA_F_HOMEADDRESS))
                    {
-                     struct rtattr *rta = IFA_RTA (ifam);
-                     size_t len = (nlmh->nlmsg_len
-                                   - NLMSG_LENGTH (sizeof (*ifam)));
-                     void *local = NULL;
-                     void *address = NULL;
-                     while (RTA_OK (rta, len))
-                       {
-                         switch (rta->rta_type)
-                           {
-                           case IFA_LOCAL:
-                             local = RTA_DATA (rta);
-                             break;
-
-                           case IFA_ADDRESS:
-                             address = RTA_DATA (rta);
-                             break;
-                           }
-
-                         rta = RTA_NEXT (rta, len);
-                       }
-
                      struct in6ailist *newp = alloca (sizeof (*newp));
                      newp->info.flags = (((ifam->ifa_flags & IFA_F_DEPRECATED)
                                           ? in6ai_deprecated : 0)
@@ -180,11 +233,11 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
 
   close_not_cancel_no_status (fd);
 
-  if (in6ailist != NULL)
+  if (*seen_ipv6 && in6ailist != NULL)
     {
       *in6ai = malloc (in6ailistlen * sizeof (**in6ai));
       if (*in6ai == NULL)
-       return -1;
+       goto out_fail;
 
       *in6ailen = in6ailistlen;
 
@@ -196,7 +249,14 @@ make_request (int fd, pid_t pid, bool *seen_ipv4, bool *seen_ipv6,
       while (in6ailist != NULL);
     }
 
+  if (use_malloc)
+    free (buf);
   return 0;
+
+out_fail:
+  if (use_malloc)
+    free (buf);
+  return -1;
 }
 
 
index ca1cc8d68e3f97bd67639b4de9d1cfa22ec39075..24ce61ba19ff17c8ef24399c76fbe2efd502253e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>.
 
@@ -30,13 +30,18 @@ static _Unwind_Reason_Code (*libgcc_s_forcedunwind)
 static _Unwind_Word (*libgcc_s_getcfa) (struct _Unwind_Context *);
 
 void
+__attribute_noinline__
 pthread_cancel_init (void)
 {
   void *resume, *personality, *forcedunwind, *getcfa;
   void *handle;
 
   if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
-    return;
+    {
+      /* Force gcc to reload all values.  */
+      asm volatile ("" ::: "memory");
+      return;
+    }
 
   handle = __libc_dlopen ("libgcc_s.so.1");
 
@@ -55,6 +60,10 @@ pthread_cancel_init (void)
   libgcc_s_resume = resume;
   libgcc_s_personality = personality;
   libgcc_s_forcedunwind = forcedunwind;
+  /* Make sure libgcc_s_getcfa is written last.  Otherwise,
+     pthread_cancel_init might return early even when the pointer the
+     caller is interested in is not initialized yet.  */
+  atomic_write_barrier ();
   libgcc_s_getcfa = getcfa;
 }
 
@@ -92,6 +101,7 @@ __gcc_personality_v0 (_Unwind_State state,
 {
   if (__builtin_expect (libgcc_s_personality == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_personality (state, ue_header, context);
 }
 
@@ -101,6 +111,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
 {
   if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_forcedunwind (exc, stop, stop_argument);
 }
 
@@ -109,5 +120,6 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
 {
   if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_getcfa (context);
 }
index 3fc647d31ddeb5cf879dffd530c2d9161f329ef6..dadfac2af2cba121ae7f21de6ef1e1a661bcf3b4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005, 2007 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
@@ -27,9 +27,6 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   ((int) ((~0u) >> 1))
-
 
 typedef union
 {
index 66a4d7b3604ec5f4a9c18dd4b4f1dbfff09c8973..44867ecc8344e3e9c2fad0e08d66d36bb4c17b27 100644 (file)
@@ -55,7 +55,8 @@ __lll_timedlock_wait (int *futex, const struct timespec *abstime)
       if (rt.tv_sec < 0)
        return ETIMEDOUT;
 
-      lll_futex_timed_wait (futex, 2, &rt);
+      // XYZ: Lost the lock to check whether it was private.
+      lll_futex_timed_wait (futex, 2, &rt, LLL_SHARED);
     }
   while (atomic_exchange_acq (futex, 2) != 0);
 
@@ -96,7 +97,8 @@ __lll_timedwait_tid (int *tidp, const struct timespec *abstime)
        return ETIMEDOUT;
 
       /* Wait until thread terminates.  */
-      if (lll_futex_timed_wait (tidp, tid, &rt) == -ETIMEDOUT)
+      // XYZ: Lost the lock to check whether it was private.
+      if (lll_futex_timed_wait (tidp, tid, &rt, LLL_SHARED) == -ETIMEDOUT)
        return ETIMEDOUT;
     }
 
index 15cf1478fd42c370495fb681b251bc18f0b875a7..468fe716fd1a40815f649bde6305e06422d88547 100644 (file)
@@ -12,7 +12,7 @@
    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 Libr   \ary; if not, write to the Free
+   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.  */
 
 #define FUTEX_TRYLOCK_PI       8
 #define FUTEX_PRIVATE_FLAG     128
 
+/* Values for 'private' parameter of locking macros.  Yes, the
+   definition seems to be backwards.  But it is not.  The bit will be
+   reversed before passing to the system call.  */
+#define LLL_PRIVATE    0
+#define LLL_SHARED     FUTEX_PRIVATE_FLAG
+
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
 
-#define lll_futex_wait(futexp, val) \
+#define lll_futex_wait(futexp, val, private) \
+  lll_futex_timed_wait(futexp, val, NULL, private)
+
+#define lll_futex_timed_wait(futexp, val, timespec, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
     __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
-                             (futexp), FUTEX_WAIT, (val), 0);                \
+                             (futexp), FUTEX_WAIT, (val), (timespec));       \
     __ret;                                                                   \
   })
 
-#define lll_futex_timed_wait(futexp, val, timespec) \
+#define lll_futex_wake(futexp, nr, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
     __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
-                             (futexp), FUTEX_WAIT, (val), (timespec));       \
+                             (futexp), FUTEX_WAKE, (nr), 0);                 \
     __ret;                                                                   \
   })
 
-#define lll_futex_wake(futexp, nr) \
+#define lll_private_futex_wait(futexp, val) \
+  lll_private_futex_timed_wait(futexp, val, NULL)
+
+#ifdef __ASSUME_PRIVATE_FUTEX
+#define lll_private_futex_timed_wait(futexp, val, timespec) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
     __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
-                             (futexp), FUTEX_WAKE, (nr), 0);                 \
+                             (futexp), FUTEX_WAIT | FUTEX_PRIVATE_FLAG,      \
+                             (val), (timespec));                             \
+    __ret;                                                                   \
+  })
+
+#define lll_private_futex_wake(futexp, nr) \
+  ({                                                                         \
+    INTERNAL_SYSCALL_DECL (__err);                                           \
+    long int __ret;                                                          \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
+                             (futexp), FUTEX_WAKE | FUTEX_PRIVATE_FLAG,      \
+                             (nr), (0));                                     \
+    __ret;                                                                   \
+  })
+#else
+#define lll_private_futex_timed_wait(futexp, val, timespec) \
+  ({                                                                         \
+    INTERNAL_SYSCALL_DECL (__err);                                           \
+    long int __ret, __op;                                                    \
+    __op = FUTEX_WAIT | THREAD_GETMEM (THREAD_SELF, header.private_futex);    \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
+                             (futexp), __op, (val), (timespec));             \
+    __ret;                                                                   \
+  })
+
+#define lll_private_futex_wake(futexp, nr) \
+  ({                                                                         \
+    INTERNAL_SYSCALL_DECL (__err);                                           \
+    long int __ret, __op;                                                    \
+    __op = FUTEX_WAKE | THREAD_GETMEM (THREAD_SELF, header.private_futex);    \
+    __ret = INTERNAL_SYSCALL (futex, __err, 4,                               \
+                             (futexp), __op, (nr), 0);                       \
     __ret;                                                                   \
   })
+#endif
 
 #define lll_robust_mutex_dead(futexv) \
   do                                                                         \
     {                                                                        \
       int *__futexp = &(futexv);                                             \
       atomic_or (__futexp, FUTEX_OWNER_DIED);                                \
-      lll_futex_wake (__futexp, 1);                                          \
+      lll_futex_wake (__futexp, 1, 0);                                       \
     }                                                                        \
   while (0)
 
 
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) \
+#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
@@ -156,7 +201,7 @@ __lll_mutex_lock (int *futex)
   if (__builtin_expect (val != 0, 0))
     {
       while (atomic_exchange_acq (futex, 2) != 0)
-       lll_futex_wait (futex, 2);
+       lll_futex_wait (futex, 2, 0);
     }
 }
 #define lll_mutex_lock(futex) __lll_mutex_lock (&(futex))
@@ -182,7 +227,7 @@ __lll_mutex_cond_lock (int *futex)
   if (__builtin_expect (val != 0, 0))
     {
       while (atomic_exchange_acq (futex, 2) != 0)
-       lll_futex_wait (futex, 2);
+       lll_futex_wait (futex, 2, 0);
     }
 }
 #define lll_mutex_cond_lock(futex) __lll_mutex_cond_lock (&(futex))
@@ -229,7 +274,7 @@ __lll_mutex_unlock (int *futex)
 {
   int val = atomic_exchange_rel (futex, 0);
   if (__builtin_expect (val > 1, 0))
-    lll_futex_wake (futex, 1);
+    lll_futex_wake (futex, 1, 0);
 }
 #define lll_mutex_unlock(futex) __lll_mutex_unlock(&(futex))
 
@@ -239,7 +284,7 @@ __lll_robust_mutex_unlock (int *futex, int mask)
 {
   int val = atomic_exchange_rel (futex, 0);
   if (__builtin_expect (val & mask, 0))
-    lll_futex_wake (futex, 1);
+    lll_futex_wake (futex, 1, 0);
 }
 #define lll_robust_mutex_unlock(futex) \
   __lll_robust_mutex_unlock(&(futex), FUTEX_WAITERS)
@@ -249,7 +294,7 @@ static inline void __attribute__ ((always_inline))
 __lll_mutex_unlock_force (int *futex)
 {
   (void) atomic_exchange_rel (futex, 0);
-  lll_futex_wake (futex, 1);
+  lll_futex_wake (futex, 1, 0);
 }
 #define lll_mutex_unlock_force(futex) __lll_mutex_unlock_force(&(futex))
 
@@ -286,7 +331,7 @@ typedef int lll_lock_t;
   do {                                 \
     __typeof (tid) __tid;              \
     while ((__tid = (tid)) != 0)       \
-      lll_futex_wait (&(tid), __tid);  \
+      lll_futex_wait (&(tid), __tid, 0);\
   } while (0)
 
 extern int __lll_timedwait_tid (int *, const struct timespec *)
index c8925810cbef1d3d11429efb004f722ce2be38a3..909e8327a53e2adcb87025ad37ffccde9ff5aac2 100644 (file)
@@ -27,7 +27,7 @@ clear_once_control (void *arg)
   pthread_once_t *once_control = (pthread_once_t *) arg;
 
   *once_control = 0;
-  lll_futex_wake (once_control, INT_MAX);
+  lll_private_futex_wake (once_control, INT_MAX);
 }
 
 int
@@ -66,7 +66,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
        break;
 
       /* Same generation, some other thread was faster. Wait.  */
-      lll_futex_wait (once_control, oldval);
+      lll_private_futex_wait (once_control, oldval);
     }
 
   /* This thread is the first here.  Do the initialization.
@@ -82,7 +82,7 @@ __pthread_once (pthread_once_t *once_control, void (*init_routine) (void))
   *once_control = __fork_generation | 2;
 
   /* Wake up all other threads.  */
-  lll_futex_wake (once_control, INT_MAX);
+  lll_private_futex_wake (once_control, INT_MAX);
 
   return 0;
 }
index ba5327a4d1a29e66d2096d4524695b02ca78c760..b2819635688a093e8e9217898db5d6d401adda3d 100644 (file)
@@ -33,6 +33,7 @@ static void (*libgcc_s_sjlj_register) (struct SjLj_Function_Context *);
 static void (*libgcc_s_sjlj_unregister) (struct SjLj_Function_Context *);
 
 void
+__attribute_noinline__
 pthread_cancel_init (void)
 {
   void *resume, *personality, *forcedunwind, *getcfa;
@@ -40,7 +41,11 @@ pthread_cancel_init (void)
   void *sjlj_register, *sjlj_unregister;
 
   if (__builtin_expect (libgcc_s_getcfa != NULL, 1))
-    return;
+    {
+      /* Force gcc to reload all values.  */
+      asm volatile ("" ::: "memory");
+      return;
+    }
 
   handle = __libc_dlopen ("libgcc_s.so.1");
 
@@ -58,9 +63,13 @@ pthread_cancel_init (void)
   libgcc_s_resume = resume;
   libgcc_s_personality = personality;
   libgcc_s_forcedunwind = forcedunwind;
-  libgcc_s_getcfa = getcfa;
   libgcc_s_sjlj_register = sjlj_register;
   libgcc_s_sjlj_unregister = sjlj_unregister;
+  /* Make sure libgcc_s_getcfa is written last.  Otherwise,
+     pthread_cancel_init might return early even when the pointer the
+     caller is interested in is not initialized yet.  */
+  atomic_write_barrier ();
+  libgcc_s_getcfa = getcfa;
 }
 
 void
@@ -68,6 +77,7 @@ _Unwind_Resume (struct _Unwind_Exception *exc)
 {
   if (__builtin_expect (libgcc_s_resume == NULL, 0))
     pthread_cancel_init ();
+
   libgcc_s_resume (exc);
 }
 
@@ -79,6 +89,7 @@ __gcc_personality_v0 (int version, _Unwind_Action actions,
 {
   if (__builtin_expect (libgcc_s_personality == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_personality (version, actions, exception_class,
                               ue_header, context);
 }
@@ -89,6 +100,7 @@ _Unwind_ForcedUnwind (struct _Unwind_Exception *exc, _Unwind_Stop_Fn stop,
 {
   if (__builtin_expect (libgcc_s_forcedunwind == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_forcedunwind (exc, stop, stop_argument);
 }
 
@@ -97,6 +109,7 @@ _Unwind_GetCFA (struct _Unwind_Context *context)
 {
   if (__builtin_expect (libgcc_s_getcfa == NULL, 0))
     pthread_cancel_init ();
+
   return libgcc_s_getcfa (context);
 }
 
@@ -105,6 +118,7 @@ _Unwind_SjLj_Register (struct SjLj_Function_Context *fc)
 {
   if (__builtin_expect (libgcc_s_sjlj_register == NULL, 0))
     pthread_cancel_init ();
+
   libgcc_s_sjlj_register (fc);
 }
 
@@ -113,5 +127,6 @@ _Unwind_SjLj_Unregister (struct SjLj_Function_Context *fc)
 {
   if (__builtin_expect (libgcc_s_sjlj_unregister == NULL, 0))
     pthread_cancel_init ();
+
   libgcc_s_sjlj_unregister (fc);
 }
index 36799aa50e475ff1a8357c6e8c36dba5a28f36bf..270a8de58aa1cdf26b367f75d2af017ce7eb5943 100644 (file)
@@ -96,7 +96,7 @@
 # define F_NOTIFY      1026    /* Request notfications on a directory.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index 90c0a481e4d141433d082455d95c18d2efb3a7f4..733a088cf5debc93a49c0b00f4086f526e66774d 100644 (file)
@@ -95,7 +95,7 @@
 # define F_NOTIFY      1026    /* Request notfications on a directory.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index d40b4b6386bdc6f702d8211e72968ecc04206daf..340466392a908d2cf589f43cf8cd13d8febfb5bd 100644 (file)
 # define F_NOTIFY      1026    /* Request notfications on a directory.  */
 #endif
 
-/* For F_[GET|SET]FL.  */
+/* For F_[GET|SET]FD.  */
 #define FD_CLOEXEC     1       /* actually anything with low bit set goes */
 
 /* For posix fcntl() and `l_type' field of a `struct flock' for lockf().  */
index c4440f9e9e906184617c80ab2e2d008656d5674a..af43a6048495920c7a94c8118f86f52143b79cf4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2005, 2007 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
@@ -29,9 +29,6 @@
 /* Value returned if `sem_open' failed.  */
 #define SEM_FAILED      ((sem_t *) 0)
 
-/* Maximum value the semaphore can have.  */
-#define SEM_VALUE_MAX   (2147483647)
-
 
 typedef union
 {