Updated to fedora-glibc-20060729T2255 fedora-glibc-2_4_90-14
authorroland <roland>
Sat, 29 Jul 2006 23:12:40 +0000 (23:12 +0000)
committerroland <roland>
Sat, 29 Jul 2006 23:12:40 +0000 (23:12 +0000)
79 files changed:
ChangeLog
NEWS
dlfcn/Makefile
dlfcn/bug-atexit3-lib.cc [new file with mode: 0644]
dlfcn/bug-atexit3.c [new file with mode: 0644]
dlfcn/dlmopen.c
fedora/branch.mk
fedora/glibc.spec.in
include/time.h
include/unistd.h
nptl/ChangeLog
nptl/Makefile
nptl/descr.h
nptl/pthreadP.h
nptl/pthread_create.c
nptl/pthread_mutex_destroy.c
nptl/pthread_mutex_init.c
nptl/pthread_mutex_lock.c
nptl/pthread_mutex_setprioceiling.c
nptl/pthread_mutex_timedlock.c
nptl/pthread_mutex_trylock.c
nptl/pthread_mutex_unlock.c
nptl/sysdeps/pthread/pthread_cond_broadcast.c
nptl/sysdeps/unix/sysv/linux/Makefile
nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/bits/posix_opt.h
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/sh/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/sparc/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
nptl/tst-mutex1.c
nptl/tst-mutex2.c
nptl/tst-mutex3.c
nptl/tst-mutex4.c
nptl/tst-mutex5.c
nptl/tst-mutex6.c
nptl/tst-mutex7.c
nptl/tst-mutex7a.c
nptl/tst-mutex9.c
nptl/tst-mutexpi1.c [new file with mode: 0644]
nptl/tst-mutexpi2.c [new file with mode: 0644]
nptl/tst-mutexpi3.c [new file with mode: 0644]
nptl/tst-mutexpi4.c [new file with mode: 0644]
nptl/tst-mutexpi5.c [new file with mode: 0644]
nptl/tst-mutexpi5a.c [new file with mode: 0644]
nptl/tst-mutexpi6.c [new file with mode: 0644]
nptl/tst-mutexpi7.c [new file with mode: 0644]
nptl/tst-mutexpi7a.c [new file with mode: 0644]
nptl/tst-mutexpi8.c [new file with mode: 0644]
nptl/tst-mutexpi9.c [new file with mode: 0644]
nptl/tst-robust1.c
nptl/tst-robust7.c
nptl/tst-robust8.c
nptl/tst-robustpi1.c [new file with mode: 0644]
nptl/tst-robustpi2.c [new file with mode: 0644]
nptl/tst-robustpi3.c [new file with mode: 0644]
nptl/tst-robustpi4.c [new file with mode: 0644]
nptl/tst-robustpi5.c [new file with mode: 0644]
nptl/tst-robustpi6.c [new file with mode: 0644]
nptl/tst-robustpi7.c [new file with mode: 0644]
nptl/tst-robustpi8.c [new file with mode: 0644]
stdlib/cxa_atexit.c
stdlib/cxa_finalize.c
stdlib/exit.h
sysdeps/unix/sysv/linux/alpha/bits/fcntl.h
sysdeps/unix/sysv/linux/i386/bits/fcntl.h
sysdeps/unix/sysv/linux/ia64/bits/fcntl.h
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h
sysdeps/unix/sysv/linux/s390/bits/fcntl.h
sysdeps/unix/sysv/linux/sh/bits/fcntl.h
sysdeps/unix/sysv/linux/sparc/bits/fcntl.h
sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h

index 7a97b2f..dfca3fc 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,45 @@
+2006-07-28  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/kernel-features.h: Define
+       __ASSUME_FUTEX_LOCK_PI.
+       * include/time.h: Declare __nanosleep_nocancel.
+       * include/unistd.h: Declare __pause_nocancel.
+
+       * dlfcn/Makefile (LDLIBS-bug-atexit3-lib.so): Use this instead of
+       LDFLAGS.  Add -lgcc_eh and libc_nonshared (again) to make sure we
+       get the __stack_chk_fail_local definition when it's needed.
+
+2006-07-26  Ulrich Drepper  <drepper@redhat.com>
+
+       * dlfcn/Makefile: Add rules to build and run bug-atexit3.
+       * dlfcn/bug-atexit3.c: New file.
+       * dlfcn/bug-atexit3-lib.cc: New file.
+
+       * dlfcn/dlmopen.c (dlmopen_doit): Don't allow RTLD_GLOBAL to be
+       used when the namespace is not the base namespace.
+
+2006-07-26  Gavin Romig-Koch  <gavin@redhat.com>
+
+       * stdlib/cxa_atexit.c (__new_exitfn_called): New variable.
+       (__new_exitfn): Bump it in every successful call.
+       * stdlib/cxa_finalize.c (__cxa_finalize): If destructor registered
+       more exit handlers, call them right away.
+       * stdlib/exit.h: Declare __new_exitfn_called.
+
+2006-07-25  Ulrich Drepper  <drepper@redhat.com>
+
+       * stdlib/cxa_finalize.c (__cxa_finalize): Fix race condition when
+       calling registered handler.
+
+       * sysdeps/unix/sysv/linux/sparc/bits/fcntl.h: Fix comment.
+       * sysdeps/unix/sysv/linux/ia64/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/bits/fcntl.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/bits/fcntl.h: Likewise.
+
 2006-07-10  Ulrich Drepper  <drepper@redhat.com>
 
        * elf/dl-lookup.c (dl_new_hash): New functions.
diff --git a/NEWS b/NEWS
index 0f73029..55855ad 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,4 +1,4 @@
-GNU C Library NEWS -- history of user-visible changes.  2006-07-10
+GNU C Library NEWS -- history of user-visible changes.  2006-07-28
 Copyright (C) 1992-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
 See the end for copying conditions.
 
@@ -33,6 +33,9 @@ Version 2.5
 
 * Support for the new ELF hash table format was added by Ulrich Drepper.
 
+* Support for priority inheritance mutexes added by Jakub Jelinek and
+  Ulrich Drepper.
+
 \f
 Version 2.4
 
index bfa1815..649f61d 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+# Copyright (C) 1995-2002, 2003, 2004, 2005, 2006 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
@@ -40,7 +40,8 @@ endif
 
 ifeq (yes,$(build-shared))
 tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
-       bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2
+       bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
+       bug-atexit3
 ifeq (yes,$(have-protected))
 tests += tstatexit
 endif
@@ -48,7 +49,7 @@ endif
 modules-names = glreflib1 glreflib2 failtestmod defaultmod1 defaultmod2 \
                errmsg1mod modatexit modcxaatexit \
                bug-dlsym1-lib1 bug-dlsym1-lib2 bug-atexit1-lib \
-               bug-atexit2-lib
+               bug-atexit2-lib bug-atexit3-lib
 
 failtestmod.so-no-z-defs = yes
 glreflib2.so-no-z-defs = yes
@@ -135,6 +136,12 @@ $(objpfx)bug-atexit2.out: $(objpfx)bug-atexit2-lib.so
 $(objpfx)bug-atexit2-lib.so: $(common-objpfx)libc.so \
                             $(common-objpfx)libc_nonshared.a
 
+LDLIBS-bug-atexit3-lib.so = -lstdc++ -lgcc_eh $(common-objpfx)libc_nonshared.a
+$(objpfx)bug-atexit3: $(libdl)
+$(objpfx)bug-atexit3.out: $(objpfx)bug-atexit3-lib.so
+$(objpfx)bug-atexit3-lib.so: $(common-objpfx)libc.so \
+                            $(common-objpfx)libc_nonshared.a
+
 
 # Depend on libc.so so a DT_NEEDED is generated in the shared objects.
 # This ensures they will load libc.so for needed symbols if loaded by
diff --git a/dlfcn/bug-atexit3-lib.cc b/dlfcn/bug-atexit3-lib.cc
new file mode 100644 (file)
index 0000000..3d01ea8
--- /dev/null
@@ -0,0 +1,23 @@
+#include <unistd.h>
+
+struct statclass
+{
+  statclass()
+  {
+    write (1, "statclass\n", 10);
+  }
+  ~statclass()
+  {
+    write (1, "~statclass\n", 11);
+  }
+};
+
+struct extclass
+{
+  ~extclass()
+  {
+    static statclass var;
+  }
+};
+
+extclass globvar;
diff --git a/dlfcn/bug-atexit3.c b/dlfcn/bug-atexit3.c
new file mode 100644 (file)
index 0000000..897eca8
--- /dev/null
@@ -0,0 +1,18 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+static int
+do_test (void)
+{
+  void *handle = dlopen ("$ORIGIN/bug-atexit3-lib.so", RTLD_LAZY);
+  if (handle == NULL)
+    {
+      printf ("dlopen failed: %s\n", dlerror ());
+      return 1;
+    }
+  dlclose (handle);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
index 0a6d47e..0c69154 100644 (file)
@@ -1,5 +1,5 @@
 /* Load a shared object at run time.
-   Copyright (C) 1995,96,97,98,99,2000,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1995-2000,2003,2004,2006 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
@@ -55,12 +55,19 @@ dlmopen_doit (void *a)
 
   /* Non-shared code has no support for multiple namespaces.  */
   if (args->nsid != LM_ID_BASE)
+    {
 # ifdef SHARED
-    /* If trying to open the link map for the main executable the namespace
-       must be the main one.  */
-    if (args->file == NULL)
+      /* If trying to open the link map for the main executable the namespace
+        must be the main one.  */
+      if (args->file == NULL)
 # endif
-      GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
+       GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid namespace"));
+
+      /* It makes no sense to use RTLD_GLOBAL when loading a DSO into
+        a namespace other than the base namespace.  */
+      if (__builtin_expect (args->mode & RTLD_GLOBAL, 0))
+       GLRO(dl_signal_error) (EINVAL, NULL, NULL, N_("invalid mode"));
+    }
 
   args->new = GLRO(dl_open) (args->file ?: "", args->mode | __RTLD_DLOPEN,
                             args->caller,
index 124031f..cd60348 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc4
-fedora-sync-date := 2006-07-10 22:06 UTC
-fedora-sync-tag := fedora-glibc-20060710T2206
+fedora-sync-date := 2006-07-29 22:55 UTC
+fedora-sync-tag := fedora-glibc-20060729T2255
index 59df1b9..7bb140e 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 13
+%define glibcrelease 14
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
 %ifarch %{xenarches}
@@ -1433,6 +1433,10 @@ rm -f *.filelist*
 %endif
 
 %changelog
+* Sat Jul 29 2006 Roland McGrath <roland@redhat.com> - 2.4.90-14
+- fix missing destructor calls in dlclose (#197932)
+- PI mutex support
+
 * Tue Jul 10 2006 Jakub Jelinek <jakub@redhat.com> 2.4.90-13
 - DT_GNU_HASH support
 
index 2247365..f2a6489 100644 (file)
@@ -81,6 +81,8 @@ extern long int __tzname_max (void);
 
 extern int __nanosleep (__const struct timespec *__requested_time,
                        struct timespec *__remaining);
+extern int __nanosleep_nocancel (__const struct timespec *__requested_time,
+                                struct timespec *__remaining);
 libc_hidden_proto(__nanosleep)
 extern int __getdate_r (__const char *__string, struct tm *__resbufp);
 
index f8f15ed..fb7a044 100644 (file)
@@ -162,5 +162,7 @@ extern __pid_t __libc_fork (void);
 /* Suspend the process until a signal arrives.
    This always returns -1 and sets `errno' to EINTR.  */
 extern int __libc_pause (void);
+/* Not cancelable variant.  */
+extern int __pause_nocancel (void);
 
 #endif
index 02b4c2f..b9705ee 100644 (file)
@@ -1,3 +1,69 @@
+2006-07-28  Ulrich Drepper  <drepper@redhat.com>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * descr.h: Change ENQUEUE_MUTEX and DEQUEUE_MUTEX for bit 0
+       notification of PI mutex.  Add ENQUEUE_MUTEX_PI.
+       * pthreadP.h: Define PTHREAD_MUTEX_PI_* macros for PI mutex types.
+       * pthread_mutex_setprioceilining.c: Adjust for mutex type name change.
+       * pthread_mutex_init.c: Add support for priority inheritance mutex.
+       * pthread_mutex_lock.c: Likewise.
+       * pthread_mutex_timedlock.c: Likewise.
+       * pthread_mutex_trylock.c: Likewise.
+       * pthread_mutex_unlock.c: Likewise.
+       * sysdeps/pthread/pthread_cond_broadcast.c: For PI mutexes wake
+       all mutexes.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.c: Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread-pi-defines.sym: New file.
+       * sysdeps/unix/sysv/linux/Makefile (gen-as-const-header): Add
+       pthread-pi-defines.sym.
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h: Define FUTEX_LOCK_PI,
+       FUTEX_UNLOCK_PI, and FUTEX_TRYLOCK_PI.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/bits/posix_opt.h: Define
+       _POSIX_THREAD_PRIO_INHERIT to 200112L.
+       * tst-mutex1.c: Adjust to allow use in PI mutex test.
+       * tst-mutex2.c: Likewise.
+       * tst-mutex3.c: Likewise.
+       * tst-mutex4.c: Likewise.
+       * tst-mutex5.c: Likewise.
+       * tst-mutex6.c: Likewise.
+       * tst-mutex7.c: Likewise.
+       * tst-mutex7a.c: Likewise.
+       * tst-mutex8.c: Likewise.
+       * tst-mutex9.c: Likewise.
+       * tst-robust1.c: Likewise.
+       * tst-robust7.c: Likewise.
+       * tst-robust8.c: Likewise.
+       * tst-mutexpi1.c: New file.
+       * tst-mutexpi2.c: New file.
+       * tst-mutexpi3.c: New file.
+       * tst-mutexpi4.c: New file.
+       * tst-mutexpi5.c: New file.
+       * tst-mutexpi6.c: New file.
+       * tst-mutexpi7.c: New file.
+       * tst-mutexpi7a.c: New file.
+       * tst-mutexpi8.c: New file.
+       * tst-mutexpi9.c: New file.
+       * tst-robust1.c: New file.
+       * tst-robust2.c: New file.
+       * tst-robust3.c: New file.
+       * tst-robust4.c: New file.
+       * tst-robust5.c: New file.
+       * tst-robust6.c: New file.
+       * tst-robust7.c: New file.
+       * tst-robust8.c: New file.
+       * Makefile (tests): Add the new tests.
+
+       * pthread_create.c (start_thread): Add some casts to avoid warnings.
+       * pthread_mutex_destroy.c: Remove unneeded label.
+
 2006-07-01  Ulrich Drepper  <drepper@redhat.com>
 
        * pthread_mutex_init.c (__pthread_mutex_init): Move some
index e430b8d..6a80bc1 100644 (file)
@@ -200,6 +200,9 @@ tests = tst-typesizes \
        tst-attr1 tst-attr2 tst-attr3 \
        tst-mutex1 tst-mutex2 tst-mutex3 tst-mutex4 tst-mutex5 tst-mutex6 \
        tst-mutex7 tst-mutex8 tst-mutex9 tst-mutex5a tst-mutex7a \
+       tst-mutexpi1 tst-mutexpi2 tst-mutexpi3 tst-mutexpi4 tst-mutexpi5 \
+       tst-mutexpi5a tst-mutexpi6 tst-mutexpi7 tst-mutexpi7a tst-mutexpi8 \
+       tst-mutexpi9 \
        tst-spin1 tst-spin2 tst-spin3 \
        tst-cond1 tst-cond2 tst-cond3 tst-cond4 tst-cond5 tst-cond6 tst-cond7 \
        tst-cond8 tst-cond9 tst-cond10 tst-cond11 tst-cond12 tst-cond13 \
@@ -207,6 +210,8 @@ tests = tst-typesizes \
        tst-cond20 tst-cond21 \
        tst-robust1 tst-robust2 tst-robust3 tst-robust4 tst-robust5 \
        tst-robust6 tst-robust7 tst-robust8 \
+       tst-robustpi1 tst-robustpi2 tst-robustpi3 tst-robustpi4 \
+       tst-robustpi5 tst-robustpi6 tst-robustpi7 tst-robustpi8 \
        tst-rwlock1 tst-rwlock2 tst-rwlock3 tst-rwlock4 tst-rwlock5 \
        tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 tst-rwlock10 \
        tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
index f89d324..607aa9f 100644 (file)
@@ -155,23 +155,28 @@ struct pthread
      first.  */
 # define QUEUE_PTR_ADJUST (offsetof (__pthread_list_t, __next))
 
-# define ENQUEUE_MUTEX(mutex) \
+# define ENQUEUE_MUTEX_BOTH(mutex, val)                                              \
   do {                                                                       \
-    __pthread_list_t *next = (THREAD_GETMEM (THREAD_SELF, robust_head.list)   \
-                             - QUEUE_PTR_ADJUST);                            \
+    __pthread_list_t *next = (__pthread_list_t *)                            \
+      ((((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_head.list)) & ~1ul)   \
+       - QUEUE_PTR_ADJUST);                                                  \
     next->__prev = (void *) &mutex->__data.__list.__next;                    \
-    mutex->__data.__list.__next = (void *) &next->__next;                    \
+    mutex->__data.__list.__next = THREAD_GETMEM (THREAD_SELF,                \
+                                                robust_head.list);           \
     mutex->__data.__list.__prev = (void *) &THREAD_SELF->robust_head;        \
     THREAD_SETMEM (THREAD_SELF, robust_head.list,                            \
-                  &mutex->__data.__list.__next);                             \
+                  (void *) (((uintptr_t) &mutex->__data.__list.__next)       \
+                            | val));                                         \
   } while (0)
 # define DEQUEUE_MUTEX(mutex) \
   do {                                                                       \
     __pthread_list_t *next = (__pthread_list_t *)                            \
-      ((char *) mutex->__data.__list.__next - QUEUE_PTR_ADJUST);             \
+      ((char *) (((uintptr_t) mutex->__data.__list.__next) & ~1ul)           \
+       - QUEUE_PTR_ADJUST);                                                  \
     next->__prev = mutex->__data.__list.__prev;                                      \
     __pthread_list_t *prev = (__pthread_list_t *)                            \
-      ((char *) mutex->__data.__list.__prev - QUEUE_PTR_ADJUST);             \
+      ((char *) (((uintptr_t) mutex->__data.__list.__prev) & ~1ul)           \
+       - QUEUE_PTR_ADJUST);                                                  \
     prev->__next = mutex->__data.__list.__next;                                      \
     mutex->__data.__list.__prev = NULL;                                              \
     mutex->__data.__list.__next = NULL;                                              \
@@ -183,27 +188,36 @@ struct pthread
     struct robust_list_head robust_head;
   };
 
-# define ENQUEUE_MUTEX(mutex) \
+# define ENQUEUE_MUTEX_BOTH(mutex, val)                                              \
   do {                                                                       \
     mutex->__data.__list.__next                                                      \
       = THREAD_GETMEM (THREAD_SELF, robust_list.__next);                     \
-    THREAD_SETMEM (THREAD_SELF, robust_list.__next, &mutex->__data.__list);   \
+    THREAD_SETMEM (THREAD_SELF, robust_list.__next,                          \
+                  ((uintptr_t) &mutex->__data.__list) | val);                \
   } while (0)
 # define DEQUEUE_MUTEX(mutex) \
   do {                                                                       \
-    __pthread_slist_t *runp = THREAD_GETMEM (THREAD_SELF, robust_list.__next);\
+    __pthread_slist_t *runp = (__pthread_slist_t *)                          \
+      (((uintptr_t) THREAD_GETMEM (THREAD_SELF, robust_list.__next)) & ~1ul); \
     if (runp == &mutex->__data.__list)                                       \
       THREAD_SETMEM (THREAD_SELF, robust_list.__next, runp->__next);         \
     else                                                                     \
       {                                                                              \
-       while (runp->__next != &mutex->__data.__list)                         \
-         runp = runp->__next;                                                \
+       __pthread_slist_t *next = (__pthread_slist_t *)               \
+         (((uintptr_t) runp->__next) & ~1ul);                                \
+       while (next != &mutex->__data.__list)                                 \
+         {                                                                   \
+           runp = next;                                                      \
+           next = (__pthread_slist_t *) (((uintptr_t) runp->__next) & ~1ul); \
+         }                                                                   \
                                                                              \
-       runp->__next = runp->__next->__next;                                  \
+       runp->__next = next->__next;                                          \
        mutex->__data.__list.__next = NULL;                                   \
       }                                                                              \
   } while (0)
 #endif
+#define ENQUEUE_MUTEX(mutex) ENQUEUE_MUTEX_BOTH (mutex, 0)
+#define ENQUEUE_MUTEX_PI(mutex) ENQUEUE_MUTEX_BOTH (mutex, 1)
 
   /* List of cleanup buffers.  */
   struct _pthread_cleanup_buffer *cleanup;
index c7f57e2..dc98bb1 100644 (file)
@@ -61,6 +61,7 @@
 /* Internal mutex type value.  */
 enum
 {
+  PTHREAD_MUTEX_KIND_MASK_NP = 3,
   PTHREAD_MUTEX_ROBUST_NORMAL_NP = 16,
   PTHREAD_MUTEX_ROBUST_RECURSIVE_NP
   = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_RECURSIVE_NP,
@@ -68,8 +69,24 @@ enum
   = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
   PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP
   = PTHREAD_MUTEX_ROBUST_NORMAL_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
-  PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP = 32,
-  PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP = 64
+  PTHREAD_MUTEX_PRIO_INHERIT_NP = 32,
+  PTHREAD_MUTEX_PI_NORMAL_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_NORMAL,
+  PTHREAD_MUTEX_PI_RECURSIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_RECURSIVE_NP,
+  PTHREAD_MUTEX_PI_ERRORCHECK_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ERRORCHECK_NP,
+  PTHREAD_MUTEX_PI_ADAPTIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ADAPTIVE_NP,
+  PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_NORMAL_NP,
+  PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_RECURSIVE_NP,
+  PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP,
+  PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP
+  = PTHREAD_MUTEX_PRIO_INHERIT_NP | PTHREAD_MUTEX_ROBUST_ADAPTIVE_NP,
+  PTHREAD_MUTEX_PRIO_PROTECT_NP = 64
 };
 #define PTHREAD_MUTEX_PRIO_CEILING_SHIFT       16
 #define PTHREAD_MUTEX_PRIO_CEILING_MASK                0x00ff0000
index 71365a1..c1ac199 100644 (file)
@@ -330,9 +330,11 @@ start_thread (void *arg)
 # else
   __pthread_slist_t *robust = pd->robust_list.__next;
 # endif
-/* We let the kernel do the notification if it is able to do so.  */
+  /* We let the kernel do the notification if it is able to do so.
+     If we have to do it here there for sure are no PI mutexes involved
+     since the kernel support for them is even more recent.  */
   if (__set_robust_list_avail < 0
-      && __builtin_expect (robust != &pd->robust_head, 0))
+      && __builtin_expect (robust != (void *) &pd->robust_head, 0))
     {
       do
        {
@@ -348,7 +350,7 @@ start_thread (void *arg)
 
          lll_robust_mutex_dead (this->__lock);
        }
-      while (robust != &pd->robust_head);
+      while (robust != (void *) &pd->robust_head);
     }
 #endif
 
index 7829979..e2c9f8a 100644 (file)
@@ -30,7 +30,6 @@ __pthread_mutex_destroy (mutex)
     return EBUSY;
 
   /* Set to an invalid value.  */
- dead_robust_mutex:
   mutex->__data.__kind = -1;
 
   return 0;
index c3f9c2d..6ceca86 100644 (file)
@@ -29,6 +29,11 @@ static const struct pthread_mutexattr default_attr =
   };
 
 
+#ifndef __ASSUME_FUTEX_LOCK_PI
+static int tpi_supported;
+#endif
+
+
 int
 __pthread_mutex_init (mutex, mutexattr)
      pthread_mutex_t *mutex;
@@ -41,8 +46,7 @@ __pthread_mutex_init (mutex, mutexattr)
   imutexattr = (const struct pthread_mutexattr *) mutexattr ?: &default_attr;
 
   /* Sanity checks.  */
-  // XXX For now we don't support priority inherited or priority protected
-  // XXX mutexes.
+  // XXX For now we don't support priority protected mutexes.
   switch (__builtin_expect (imutexattr->mutexkind
                            & PTHREAD_MUTEXATTR_PROTOCOL_MASK,
                            PTHREAD_PRIO_NONE
@@ -51,6 +55,22 @@ __pthread_mutex_init (mutex, mutexattr)
     case PTHREAD_PRIO_NONE << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
       break;
 
+    case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
+#ifndef __ASSUME_FUTEX_LOCK_PI
+      if (__builtin_expect (tpi_supported == 0, 0))
+       {
+         int lock = 0;
+         INTERNAL_SYSCALL_DECL (err);
+         int ret = INTERNAL_SYSCALL (futex, err, 4, &lock, FUTEX_UNLOCK_PI,
+                                     0, 0);
+         assert (INTERNAL_SYSCALL_ERROR_P (ret, err));
+         tpi_supported = INTERNAL_SYSCALL_ERRNO (ret, err) == ENOSYS ? -1 : 1;
+       }
+      if (__builtin_expect (tpi_supported < 0, 0))
+       return ENOTSUP;
+#endif
+      break;
+
     default:
       return ENOTSUP;
     }
@@ -75,11 +95,11 @@ __pthread_mutex_init (mutex, mutexattr)
   switch (imutexattr->mutexkind & PTHREAD_MUTEXATTR_PROTOCOL_MASK)
     {
     case PTHREAD_PRIO_INHERIT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
-      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_PRIVATE_NP;
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_INHERIT_NP;
       break;
 
     case PTHREAD_PRIO_PROTECT << PTHREAD_MUTEXATTR_PROTOCOL_SHIFT:
-      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP;
+      mutex->__data.__kind |= PTHREAD_MUTEX_PRIO_PROTECT_NP;
       if (PTHREAD_MUTEX_PRIO_CEILING_MASK
          == PTHREAD_MUTEXATTR_PRIO_CEILING_MASK)
        mutex->__data.__kind |= (imutexattr->mutexkind
index 06eef49..5345766 100644 (file)
@@ -20,6 +20,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
+#include <unistd.h>
 #include "pthreadP.h"
 #include <lowlevellock.h>
 
@@ -205,6 +206,134 @@ __pthread_mutex_lock (mutex)
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+       int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+       int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+       if (robust)
+         /* Note: robust PI futexes are signaled by setting bit 0.  */
+         THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                        (void *) (((uintptr_t) &mutex->__data.__list.__next)
+                                  | 1));
+
+       oldval = mutex->__data.__lock;
+
+       /* Check whether we already hold the mutex.  */
+       if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+         {
+           if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+               return EDEADLK;
+             }
+
+           if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+               /* Just bump the counter.  */
+               if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+                 /* Overflow of the counter.  */
+                 return EAGAIN;
+
+               ++mutex->__data.__count;
+
+               return 0;
+             }
+         }
+
+       int newval = id;
+#ifdef NO_INCR
+       newval |= FUTEX_WAITERS;
+#endif
+       oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                                     newval, 0);
+
+       if (oldval != 0)
+         {
+           /* The mutex is locked.  The kernel will now take care of
+              everything.  */
+           INTERNAL_SYSCALL_DECL (__err);
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_LOCK_PI, 1, 0);
+
+           if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+               && (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
+                   || INTERNAL_SYSCALL_ERRNO (e, __err) == EDEADLK))
+             {
+               assert (INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK
+                       || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
+                           && kind != PTHREAD_MUTEX_RECURSIVE_NP));
+               /* ESRCH can happen only for non-robust PI mutexes where
+                  the owner of the lock died.  */
+               assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH || !robust);
+
+               /* Delay the thread indefinitely.  */
+               while (1)
+                 __pause_nocancel ();
+             }
+
+           oldval = mutex->__data.__lock;
+
+           assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
+         }
+
+       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+         {
+           atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+           /* We got the mutex.  */
+           mutex->__data.__count = 1;
+           /* But it is inconsistent unless marked otherwise.  */
+           mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+           ENQUEUE_MUTEX_PI (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+           /* Note that we deliberately exit here.  If we fall
+              through to the end of the function __nusers would be
+              incremented which is not correct because the old owner
+              has to be discounted.  If we are not supposed to
+              increment __nusers we actually have to decrement it here.  */
+#ifdef NO_INCR
+           --mutex->__data.__nusers;
+#endif
+
+           return EOWNERDEAD;
+         }
+
+       if (robust
+           && __builtin_expect (mutex->__data.__owner
+                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+         {
+           /* This mutex is now not recoverable.  */
+           mutex->__data.__count = 0;
+
+           INTERNAL_SYSCALL_DECL (__err);
+           INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                             FUTEX_UNLOCK_PI, 0, 0);
+
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+           return ENOTRECOVERABLE;
+         }
+
+       mutex->__data.__count = 1;
+       if (robust)
+         {
+           ENQUEUE_MUTEX_PI (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+         }
+      }
+      break;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 999b635..3271f88 100644 (file)
@@ -30,7 +30,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
 {
   /* The low bits of __kind aren't ever changed after pthread_mutex_init,
      so we don't need a lock yet.  */
-  if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_PRIVATE_NP) == 0)
+  if ((mutex->__data.__kind & PTHREAD_MUTEX_PRIO_PROTECT_NP) == 0)
     return EINVAL;
 
   if (prioceiling < 0 || __builtin_expect (prioceiling > 255, 0))
index 7c48c7c..12f6c99 100644 (file)
@@ -35,7 +35,7 @@ pthread_mutex_timedlock (mutex, abstime)
   /* We must not check ABSTIME here.  If the thread does not block
      abstime must not be checked for a valid value.  */
 
-  switch (mutex->__data.__kind)
+  switch (__builtin_expect (mutex->__data.__kind, PTHREAD_MUTEX_TIMED_NP))
     {
       /* Recursive mutex.  */
     case PTHREAD_MUTEX_RECURSIVE_NP:
@@ -65,7 +65,7 @@ pthread_mutex_timedlock (mutex, abstime)
       /* Error checking mutex.  */
     case PTHREAD_MUTEX_ERRORCHECK_NP:
       /* Check whether we already hold the mutex.  */
-      if (mutex->__data.__owner == id)
+      if (__builtin_expect (mutex->__data.__owner == id, 0))
        return EDEADLK;
 
       /* FALLTHROUGH */
@@ -134,7 +134,7 @@ pthread_mutex_timedlock (mutex, abstime)
              ENQUEUE_MUTEX (mutex);
              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
 
-             /* Note that we deliberately exist here.  If we fall
+             /* Note that we deliberately exit here.  If we fall
                 through to the end of the function __nusers would be
                 incremented which is not correct because the old
                 owner has to be discounted.  */
@@ -194,6 +194,150 @@ pthread_mutex_timedlock (mutex, abstime)
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+       int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+       int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+       if (robust)
+         /* Note: robust PI futexes are signaled by setting bit 0.  */
+         THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                        (void *) (((uintptr_t) &mutex->__data.__list.__next)
+                                  | 1));
+
+       oldval = mutex->__data.__lock;
+
+       /* Check whether we already hold the mutex.  */
+       if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+         {
+           if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+               return EDEADLK;
+             }
+
+           if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+               /* Just bump the counter.  */
+               if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+                 /* Overflow of the counter.  */
+                 return EAGAIN;
+
+               ++mutex->__data.__count;
+
+               return 0;
+             }
+         }
+
+       oldval = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                                     id, 0);
+
+       if (oldval != 0)
+         {
+           /* The mutex is locked.  The kernel will now take care of
+              everything.  The timeout value must be a relative value.
+              Convert it.  */
+           INTERNAL_SYSCALL_DECL (__err);
+
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_LOCK_PI, 1, abstime);
+           if (INTERNAL_SYSCALL_ERROR_P (e, __err))
+             {
+               if (INTERNAL_SYSCALL_ERRNO (e, __err) == ETIMEDOUT)
+                 return ETIMEDOUT;
+
+               if (INTERNAL_SYSCALL_ERRNO (e, __err) == ESRCH
+                   || INTERNAL_SYSCALL_ERRNO (e, __err) == EDEADLK)
+                 {
+                   assert (INTERNAL_SYSCALL_ERRNO (e, __err) != EDEADLK
+                           || (kind != PTHREAD_MUTEX_ERRORCHECK_NP
+                               && kind != PTHREAD_MUTEX_RECURSIVE_NP));
+                   /* ESRCH can happen only for non-robust PI mutexes where
+                      the owner of the lock died.  */
+                   assert (INTERNAL_SYSCALL_ERRNO (e, __err) != ESRCH
+                           || !robust);
+
+                   /* Delay the thread until the timeout is reached.
+                      Then return ETIMEDOUT.  */
+                   struct timespec reltime;
+                   struct timespec now;
+
+                   INTERNAL_SYSCALL (clock_gettime, __err, 2, CLOCK_REALTIME,
+                                     &now);
+                   reltime.tv_sec = abstime->tv_sec - now.tv_sec;
+                   reltime.tv_nsec = abstime->tv_nsec - now.tv_nsec;
+                   if (reltime.tv_nsec < 0)
+                     {
+                       reltime.tv_nsec += 1000000000;
+                       --reltime.tv_sec;
+                     }
+                   if (reltime.tv_sec >= 0)
+                     while (__nanosleep_nocancel (&reltime, &reltime) != 0)
+                       continue;
+
+                   return ETIMEDOUT;
+                 }
+
+               return INTERNAL_SYSCALL_ERRNO (e, __err);
+             }
+
+           oldval = mutex->__data.__lock;
+
+           assert (robust || (oldval & FUTEX_OWNER_DIED) == 0);
+         }
+
+       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+         {
+           atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+           /* We got the mutex.  */
+           mutex->__data.__count = 1;
+           /* But it is inconsistent unless marked otherwise.  */
+           mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+           ENQUEUE_MUTEX_PI (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+           /* Note that we deliberately exit here.  If we fall
+              through to the end of the function __nusers would be
+              incremented which is not correct because the old owner
+              has to be discounted.  */
+           return EOWNERDEAD;
+         }
+
+       if (robust
+           && __builtin_expect (mutex->__data.__owner
+                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+         {
+           /* This mutex is now not recoverable.  */
+           mutex->__data.__count = 0;
+
+           INTERNAL_SYSCALL_DECL (__err);
+           INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                             FUTEX_UNLOCK_PI, 0, 0);
+
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+           return ENOTRECOVERABLE;
+         }
+
+       mutex->__data.__count = 1;
+       if (robust)
+         {
+           ENQUEUE_MUTEX_PI (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+         }
+       }
+      break;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 148a6e9..f3a1856 100644 (file)
@@ -152,7 +152,6 @@ __pthread_mutex_trylock (mutex)
              return EBUSY;
            }
 
-       robust:
          if (__builtin_expect (mutex->__data.__owner
                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
            {
@@ -175,6 +174,129 @@ __pthread_mutex_trylock (mutex)
 
       return 0;
 
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      {
+       int kind = mutex->__data.__kind & PTHREAD_MUTEX_KIND_MASK_NP;
+       int robust = mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP;
+
+       if (robust)
+         /* Note: robust PI futexes are signaled by setting bit 0.  */
+         THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                        (void *) (((uintptr_t) &mutex->__data.__list.__next)
+                                  | 1));
+
+       oldval = mutex->__data.__lock;
+
+       /* Check whether we already hold the mutex.  */
+       if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
+         {
+           if (kind == PTHREAD_MUTEX_ERRORCHECK_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+               return EDEADLK;
+             }
+
+           if (kind == PTHREAD_MUTEX_RECURSIVE_NP)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+               /* Just bump the counter.  */
+               if (__builtin_expect (mutex->__data.__count + 1 == 0, 0))
+                 /* Overflow of the counter.  */
+                 return EAGAIN;
+
+               ++mutex->__data.__count;
+
+               return 0;
+             }
+         }
+
+       oldval
+         = atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
+                                                id, 0);
+
+       if (oldval != 0)
+         {
+           if ((oldval & FUTEX_OWNER_DIED) == 0)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+               return EBUSY;
+             }
+
+           assert (robust);
+
+           /* The mutex owner died.  The kernel will now take care of
+              everything.  */
+           INTERNAL_SYSCALL_DECL (__err);
+           int e = INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                                     FUTEX_TRYLOCK_PI, 0, 0);
+
+           if (INTERNAL_SYSCALL_ERROR_P (e, __err)
+               && INTERNAL_SYSCALL_ERRNO (e, __err) == EWOULDBLOCK)
+             {
+               THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+               return EBUSY;
+             }
+
+           oldval = mutex->__data.__lock;
+         }
+
+       if (__builtin_expect (oldval & FUTEX_OWNER_DIED, 0))
+         {
+           atomic_and (&mutex->__data.__lock, ~FUTEX_OWNER_DIED);
+
+           /* We got the mutex.  */
+           mutex->__data.__count = 1;
+           /* But it is inconsistent unless marked otherwise.  */
+           mutex->__data.__owner = PTHREAD_MUTEX_INCONSISTENT;
+
+           ENQUEUE_MUTEX (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+
+           /* Note that we deliberately exit here.  If we fall
+              through to the end of the function __nusers would be
+              incremented which is not correct because the old owner
+              has to be discounted.  */
+           return EOWNERDEAD;
+         }
+
+       if (robust
+           && __builtin_expect (mutex->__data.__owner
+                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
+         {
+           /* This mutex is now not recoverable.  */
+           mutex->__data.__count = 0;
+
+           INTERNAL_SYSCALL_DECL (__err);
+           INTERNAL_SYSCALL (futex, __err, 4, &mutex->__data.__lock,
+                             FUTEX_UNLOCK_PI, 0, 0);
+
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+           return ENOTRECOVERABLE;
+         }
+
+       if (robust)
+         {
+           ENQUEUE_MUTEX_PI (mutex);
+           THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+         }
+
+       mutex->__data.__owner = id;
+       ++mutex->__data.__nusers;
+       mutex->__data.__count = 1;
+
+       return 0;
+      }
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index bf9aa76..2b5064f 100644 (file)
@@ -119,6 +119,89 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
 
+    case PTHREAD_MUTEX_PI_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+       return EPERM;
+
+      if (--mutex->__data.__count != 0)
+       /* We still hold the mutex.  */
+       return 0;
+      goto continue_pi;
+
+    case PTHREAD_MUTEX_PI_ROBUST_RECURSIVE_NP:
+      /* Recursive mutex.  */
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+         == THREAD_GETMEM (THREAD_SELF, tid)
+         && __builtin_expect (mutex->__data.__owner
+                              == PTHREAD_MUTEX_INCONSISTENT, 0))
+       {
+         if (--mutex->__data.__count != 0)
+           /* We still hold the mutex.  */
+           return ENOTRECOVERABLE;
+
+         goto pi_notrecoverable;
+       }
+
+      if (mutex->__data.__owner != THREAD_GETMEM (THREAD_SELF, tid))
+       return EPERM;
+
+      if (--mutex->__data.__count != 0)
+       /* We still hold the mutex.  */
+       return 0;
+
+      goto continue_pi;
+
+    case PTHREAD_MUTEX_PI_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ADAPTIVE_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ERRORCHECK_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_NORMAL_NP:
+    case PTHREAD_MUTEX_PI_ROBUST_ADAPTIVE_NP:
+      if ((mutex->__data.__lock & FUTEX_TID_MASK)
+         != THREAD_GETMEM (THREAD_SELF, tid)
+         || ! lll_mutex_islocked (mutex->__data.__lock))
+       return EPERM;
+
+      /* If the previous owner died and the caller did not succeed in
+        making the state consistent, mark the mutex as unrecoverable
+        and make all waiters.  */
+      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0
+         && __builtin_expect (mutex->__data.__owner
+                              == PTHREAD_MUTEX_INCONSISTENT, 0))
+      pi_notrecoverable:
+       newowner = PTHREAD_MUTEX_NOTRECOVERABLE;
+
+    continue_pi:
+      if ((mutex->__data.__kind & PTHREAD_MUTEX_ROBUST_NORMAL_NP) != 0)
+       {
+         /* Remove mutex from the list.
+            Note: robust PI futexes are signaled by setting bit 0.  */
+         THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
+                        (void *) (((uintptr_t) &mutex->__data.__list.__next)
+                                  | 1));
+         DEQUEUE_MUTEX (mutex);
+       }
+
+      mutex->__data.__owner = newowner;
+      if (decr)
+       /* One less user.  */
+       --mutex->__data.__nusers;
+
+      /* Unlock.  */
+      if ((mutex->__data.__lock & FUTEX_WAITERS) != 0
+         || atomic_compare_and_exchange_bool_acq (&mutex->__data.__lock, 0,
+                                                  THREAD_GETMEM (THREAD_SELF,
+                                                                 tid)))
+       {
+         INTERNAL_SYSCALL_DECL (__err);
+         INTERNAL_SYSCALL (futex, __err, 2, &mutex->__data.__lock,
+                           FUTEX_UNLOCK_PI);
+       }
+
+      THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
+      break;
+
     default:
       /* Correct code cannot set any other type.  */
       return EINVAL;
index 1eac8ec..2b8b546 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -55,6 +55,12 @@ __pthread_cond_broadcast (cond)
 
       /* Wake everybody.  */
       pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
+
+      /* XXX: Kernel so far doesn't support requeue to PI futex.  */
+      if (__builtin_expect (mut->__data.__kind & PTHREAD_MUTEX_PRIO_INHERIT_NP,
+                           0))
+       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,
index 88dce1a..cfcdb6d 100644 (file)
@@ -25,7 +25,7 @@ libpthread-sysdep_routines += pt-fork pthread_mutex_cond_lock
 
 gen-as-const-headers += lowlevelcond.sym lowlevelrwlock.sym \
                        lowlevelbarrier.sym unwindbuf.sym \
-                       lowlevelrobustlock.sym
+                       lowlevelrobustlock.sym pthread-pi-defines.sym
 endif
 
 ifeq ($(subdir),posix)
index 1a2e8cb..58b4806 100644 (file)
@@ -33,6 +33,9 @@
 #define FUTEX_CMP_REQUEUE      4
 #define FUTEX_WAKE_OP          5
 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
index 92c2d32..d8eced1 100644 (file)
@@ -1,5 +1,5 @@
 /* Define POSIX options for Linux.
-   Copyright (C) 1996-2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2004, 2006 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
@@ -79,6 +79,9 @@
 /* We support user-defined stacks.  */
 #define _POSIX_THREAD_ATTR_STACKADDR   200112L
 
+/* We support priority inheritence.  */
+#define _POSIX_THREAD_PRIO_INHERIT     200112L
+
 /* We support POSIX.1b semaphores.  */
 #define _POSIX_SEMAPHORES      200112L
 
 /* Typed memory objects are not available.  */
 #define _POSIX_TYPED_MEMORY_OBJECTS    -1
 
-/* No support for priority inheritance or protection so far.  */
-#define _POSIX_THREAD_PRIO_INHERIT     -1
+/* No support for priority protection so far.  */
 #define _POSIX_THREAD_PRIO_PROTECT     -1
 
 #endif /* posix_opt.h */
index 5471c1c..56f7be8 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -94,6 +95,10 @@ __pthread_cond_broadcast:
 8:     cmpl    $-1, %edi
        je      9f
 
+       /* XXX: The kernel so far doesn't support requeue to PI futex.  */
+       testl   $PI_BIT, MUTEX_KIND(%edi)
+       jne     9f
+
        /* Wake up all threads.  */
        movl    $FUTEX_CMP_REQUEUE, %ecx
        movl    $SYS_futex, %eax
index e405f84..64088ef 100644 (file)
@@ -35,6 +35,9 @@
 #define SYS_futex              240
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 
 /* Initializer for compatibility lock.  */
index ece9a7f..8df997a 100644 (file)
@@ -33,6 +33,9 @@
 #define FUTEX_CMP_REQUEUE      4
 #define FUTEX_WAKE_OP          5
 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 /* Delay in spinlock loop.  */
 #define BUSY_WAIT_NOP          asm ("hint @pause")
index abd019d..0136b97 100644 (file)
@@ -35,6 +35,9 @@
 #define FUTEX_CMP_REQUEUE      4
 #define FUTEX_WAKE_OP          5
 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym b/nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
new file mode 100644 (file)
index 0000000..a1b6794
--- /dev/null
@@ -0,0 +1,6 @@
+#include <pthreadP.h>
+
+-- These PI macros are used by assembly code.
+
+MUTEX_KIND     offsetof (pthread_mutex_t, __data.__kind)
+PI_BIT         PTHREAD_MUTEX_PRIO_INHERIT_NP
index 6baab90..38d9f2a 100644 (file)
@@ -32,6 +32,9 @@
 #define FUTEX_CMP_REQUEUE      4
 #define FUTEX_WAKE_OP          5
 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
index 92f93cd..0eb1f01 100644 (file)
@@ -26,6 +26,9 @@
 #define SYS_futex              240
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 
 /* Initializer for compatibility lock.  */
index 77eefc5..5013922 100644 (file)
@@ -32,6 +32,9 @@
 #define FUTEX_CMP_REQUEUE      4
 #define FUTEX_WAKE_OP          5
 #define FUTEX_OP_CLEAR_WAKE_IF_GT_ONE  ((4 << 24) | 1)
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 /* Initializer for compatibility lock. */
 #define LLL_MUTEX_LOCK_INITIALIZER (0)
index 5047e4f..7da2f12 100644 (file)
@@ -35,6 +35,9 @@
 #define SYS_futex              202
 #define FUTEX_WAIT             0
 #define FUTEX_WAKE             1
+#define FUTEX_LOCK_PI          6
+#define FUTEX_UNLOCK_PI                7
+#define FUTEX_TRYLOCK_PI       8
 
 
 /* Initializer for compatibility lock.  */
index 72e7bc5..006de26 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -21,6 +21,7 @@
 #include <shlib-compat.h>
 #include <lowlevelcond.h>
 #include <kernel-features.h>
+#include <pthread-pi-defines.h>
 
 #ifdef UP
 # define LOCK
@@ -80,6 +81,10 @@ __pthread_cond_broadcast:
 8:     cmpq    $-1, %r8
        je      9f
 
+       /* XXX: The kernel so far doesn't support requeue to PI futex.  */
+       testl   $PI_BIT, MUTEX_KIND(%r8)
+       jne     9f
+
        /* Wake up all threads.  */
        movl    $FUTEX_CMP_REQUEUE, %esi
        movl    $SYS_futex, %eax
index 50b5cca..c3ef5b2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 
 #include <pthread.h>
 #include <stdio.h>
+#include <errno.h>
+
+
+#ifndef ATTR
+# define ATTR NULL
+#endif
 
 
 static int
@@ -26,12 +32,24 @@ do_test (void)
 {
   pthread_mutex_t m;
 
-  if (pthread_mutex_init (&m, NULL) != 0)
+  int e = pthread_mutex_init (&m, ATTR);
+  if (ATTR != NULL && e == ENOTSUP)
+    {
+      puts ("cannot support selected type of mutexes");
+      return 0;
+    }
+  else if (e != 0)
     {
       puts ("mutex_init failed");
       return 1;
     }
 
+  if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("mutex_lock failed");
index f589a1e..b09f569 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -105,115 +105,134 @@ do_test (void)
   if (pthread_mutexattr_init (&a) != 0)
     {
       puts ("mutexattr_init failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_ERRORCHECK) != 0)
     {
       puts ("mutexattr_settype failed");
-      exit (1);
+      return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_barrier_init (&b, NULL, 2) != 0)
     {
       puts ("barrier_init failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_unlock (&m)) == 0)
+  e = pthread_mutex_unlock (&m);
+  if (e == 0)
     {
       puts ("1st mutex_unlock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EPERM)
     {
       puts ("1st mutex_unlock error != EPERM");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("mutex_lock failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_lock (&m)) == 0)
+  e = pthread_mutex_lock (&m);
+  if (e == 0)
     {
       puts ("2nd mutex_lock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EDEADLK)
     {
       puts ("2nd mutex_lock error != EDEADLK");
-      exit (1);
+      return 1;
     }
 
   pthread_t th;
   if (pthread_create (&th, NULL, tf, NULL) != 0)
     {
       puts ("create failed");
-      exit (1);
+      return 1;
     }
 
   e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("1st barrier_wait failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_unlock (&m) != 0)
     {
       puts ("2nd mutex_unlock failed");
-      exit (1);
+      return 1;
     }
 
-  if ((e = pthread_mutex_unlock (&m)) == 0)
+  e = pthread_mutex_unlock (&m);
+  if (e == 0)
     {
       puts ("3rd mutex_unlock succeeded");
-      exit (1);
+      return 1;
     }
   else if (e != EPERM)
     {
       puts ("3rd mutex_unlock error != EPERM");
-      exit (1);
+      return 1;
     }
 
   e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("2nd barrier_wait failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_join (th, NULL) != 0)
     {
       puts ("join failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutex_destroy (&m) != 0)
     {
       puts ("mutex_destroy failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_barrier_destroy (&b) != 0)
     {
       puts ("barrier_destroy failed");
-      exit (1);
+      return 1;
     }
 
   if (pthread_mutexattr_destroy (&a) != 0)
     {
       puts ("mutexattr_destroy failed");
-      exit (1);
+      return 1;
     }
 
   return 0;
index 8e57924..2848096 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -113,8 +113,25 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -162,7 +179,7 @@ do_test (void)
       return 1;
     }
 
-  int e = pthread_barrier_wait (&b);
+  e = pthread_barrier_wait (&b);
   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
     {
       puts ("barrier_wait failed");
index 0ce7313..9699c2d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -42,6 +42,8 @@ do_test (void)
   char *p;
   int err;
   int s;
+  pthread_barrier_t *b;
+  pthread_barrierattr_t ba;
 
   fd = mkstemp (tmpfname);
   if (fd == -1)
@@ -70,9 +72,12 @@ do_test (void)
       return 1;
     }
 
-  m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t))
+  m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1)
                           & ~(__alignof (pthread_mutex_t) - 1));
-  p = (char *) (m + 1);
+  b = (pthread_barrier_t *) (((uintptr_t) (m + 1)
+                             + __alignof (pthread_barrier_t) - 1)
+                            & ~(__alignof (pthread_barrier_t) - 1));
+  p = (char *) (b + 1);
 
   if (pthread_mutexattr_init (&a) != 0)
     {
@@ -110,8 +115,23 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  if ((err = pthread_mutex_init (m, &a)) != 0)
+    {
+#ifdef ENABLE_PI
+      if (err == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -128,6 +148,30 @@ do_test (void)
       return 1;
     }
 
+  if (pthread_barrierattr_init (&ba) != 0)
+    {
+      puts ("barrierattr_init failed");
+      return 1;
+    }
+
+  if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
+    {
+      puts ("barrierattr_setpshared failed");
+      return 1;
+    }
+
+  if (pthread_barrier_init (b, &ba, 2) != 0)
+    {
+      puts ("barrier_init failed");
+      return 1;
+    }
+
+  if (pthread_barrierattr_destroy (&ba) != 0)
+    {
+      puts ("barrierattr_destroy failed");
+      return 1;
+    }
+
   err = pthread_mutex_trylock (m);
   if (err == 0)
     {
@@ -142,6 +186,12 @@ do_test (void)
 
   *p = 0;
 
+  if (pthread_mutex_unlock (m) != 0)
+    {
+      puts ("parent: 1st mutex_unlock failed");
+      return 1;
+    }
+
   puts ("going to fork now");
   pid = fork ();
   if (pid == -1)
@@ -151,7 +201,19 @@ do_test (void)
     }
   else if (pid == 0)
     {
-      /* Play some lock ping-pong.  It's our turn to unlock first.  */
+      if (pthread_mutex_lock (m) != 0)
+       {
+         puts ("child: mutex_lock failed");
+         return 1;
+       }
+
+      int e = pthread_barrier_wait (b);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("child: barrier_wait failed");
+         return 1;
+       }
+
       if ((*p)++ != 0)
        {
          puts ("child: *p != 0");
@@ -160,7 +222,7 @@ do_test (void)
 
       if (pthread_mutex_unlock (m) != 0)
        {
-         puts ("child: 1st mutex_unlock failed");
+         puts ("child: mutex_unlock failed");
          return 1;
        }
 
@@ -168,6 +230,13 @@ do_test (void)
     }
   else
     {
+      int e = pthread_barrier_wait (b);
+      if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
+       {
+         puts ("parent: barrier_wait failed");
+         return 1;
+       }
+
       if (pthread_mutex_lock (m) != 0)
        {
          puts ("parent: 2nd mutex_lock failed");
@@ -180,6 +249,24 @@ do_test (void)
          return 1;
        }
 
+      if (pthread_mutex_unlock (m) != 0)
+       {
+         puts ("parent: 2nd mutex_unlock failed");
+         return 1;
+       }
+
+      if (pthread_mutex_destroy (m) != 0)
+       {
+         puts ("mutex_destroy failed");
+         return 1;
+       }
+
+      if (pthread_barrier_destroy (b) != 0)
+       {
+         puts ("barrier_destroy failed");
+         return 1;
+       }
+
       puts ("parent done");
     }
 
index eb35b78..291274f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -52,8 +52,24 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  err = pthread_mutex_init (&m, &a);
+  if (err != 0)
+    {
+#ifdef ENABLE_PI
+      if (err == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
index f066c62..e5698c3 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
 #include <signal.h>
 #include <stdio.h>
 #include <unistd.h>
+#include <errno.h>
+
+
+#ifndef ATTR
+# define ATTR NULL
+#endif
 
 
 static int
@@ -28,12 +34,24 @@ do_test (void)
 {
   pthread_mutex_t m;
 
-  if (pthread_mutex_init (&m, NULL) != 0)
+  int e = pthread_mutex_init (&m, ATTR);
+  if (ATTR != NULL && e == ENOTSUP)
+    {
+      puts ("cannot support selected type of mutexes");
+      e = pthread_mutex_init (&m, NULL);
+    }
+  if (e != 0)
     {
       puts ("mutex_init failed");
       return 1;
     }
 
+  if (ATTR != NULL && pthread_mutexattr_destroy (ATTR) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   if (pthread_mutex_lock (&m) != 0)
     {
       puts ("1st mutex_lock failed");
index a9b9f31..27e5d8e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <errno.h>
 #include <pthread.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <time.h>
 
 
-#ifndef INIT
-# define INIT PTHREAD_MUTEX_INITIALIZER
+#ifndef TYPE
+# define TYPE PTHREAD_MUTEX_DEFAULT
 #endif
 
 
-static pthread_mutex_t lock = INIT;
+static pthread_mutex_t lock;
 
 
 #define ROUNDS 1000
@@ -65,6 +67,48 @@ tf (void *arg)
 static int
 do_test (void)
 {
+  pthread_mutexattr_t a;
+
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_settype (&a, TYPE) != 0)
+    {
+      puts ("mutexattr_settype failed");
+      exit (1);
+    }
+
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e = pthread_mutex_init (&lock, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
+      puts ("mutex_init failed");
+      return 1;
+    }
+
+  if (pthread_mutexattr_destroy (&a) != 0)
+    {
+      puts ("mutexattr_destroy failed");
+      return 1;
+    }
+
   pthread_attr_t at;
   pthread_t th[N];
   int cnt;
index f08799a..30d46b8 100644 (file)
@@ -1,2 +1,2 @@
-#define INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
+#define TYPE PTHREAD_MUTEX_ADAPTIVE_NP
 #include "tst-mutex7.c"
index 5ea2f0a..f9d3793 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -88,8 +88,24 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  if ((e = pthread_mutex_init (m, &a)) != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI mutexes unsupported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -138,7 +154,7 @@ do_test (void)
          ts.tv_nsec -= 1000000000;
        }
 
-      int e = pthread_mutex_timedlock (m, &ts);
+      e = pthread_mutex_timedlock (m, &ts);
       if (e == 0)
        {
          puts ("child: mutex_timedlock succeeded");
diff --git a/nptl/tst-mutexpi1.c b/nptl/tst-mutexpi1.c
new file mode 100644 (file)
index 0000000..623ede9
--- /dev/null
@@ -0,0 +1,27 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutexattr_t a;
+
+static void
+prepare (void)
+{
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("mutexattr_setprotocol failed");
+      exit (1);
+    }
+}
+#define PREPARE(argc, argv) prepare ()
+
+
+#define ATTR &a
+#include "tst-mutex1.c"
diff --git a/nptl/tst-mutexpi2.c b/nptl/tst-mutexpi2.c
new file mode 100644 (file)
index 0000000..fbe4871
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex2.c"
diff --git a/nptl/tst-mutexpi3.c b/nptl/tst-mutexpi3.c
new file mode 100644 (file)
index 0000000..e338ebf
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex3.c"
diff --git a/nptl/tst-mutexpi4.c b/nptl/tst-mutexpi4.c
new file mode 100644 (file)
index 0000000..177b17b
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex4.c"
diff --git a/nptl/tst-mutexpi5.c b/nptl/tst-mutexpi5.c
new file mode 100644 (file)
index 0000000..287465c
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex5.c"
diff --git a/nptl/tst-mutexpi5a.c b/nptl/tst-mutexpi5a.c
new file mode 100644 (file)
index 0000000..2f85c94
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex5a.c"
diff --git a/nptl/tst-mutexpi6.c b/nptl/tst-mutexpi6.c
new file mode 100644 (file)
index 0000000..42cda37
--- /dev/null
@@ -0,0 +1,27 @@
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+
+static pthread_mutexattr_t a;
+
+static void
+prepare (void)
+{
+  if (pthread_mutexattr_init (&a) != 0)
+    {
+      puts ("mutexattr_init failed");
+      exit (1);
+    }
+
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("mutexattr_setprotocol failed");
+      exit (1);
+    }
+}
+#define PREPARE(argc, argv) prepare ()
+
+
+#define ATTR &a
+#include "tst-mutex6.c"
diff --git a/nptl/tst-mutexpi7.c b/nptl/tst-mutexpi7.c
new file mode 100644 (file)
index 0000000..1e7e929
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex7.c"
diff --git a/nptl/tst-mutexpi7a.c b/nptl/tst-mutexpi7a.c
new file mode 100644 (file)
index 0000000..c59083c
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex7a.c"
diff --git a/nptl/tst-mutexpi8.c b/nptl/tst-mutexpi8.c
new file mode 100644 (file)
index 0000000..cea6030
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex8.c"
diff --git a/nptl/tst-mutexpi9.c b/nptl/tst-mutexpi9.c
new file mode 100644 (file)
index 0000000..3710d9e
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-mutex9.c"
index 9806ca4..bc48700 100644 (file)
@@ -97,6 +97,30 @@ do_test (void)
       puts ("mutexattr_setrobust failed");
       return 1;
     }
+
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+  else
+    {
+      int e = pthread_mutex_init (&m1, &a);
+      if (e == ENOTSUP)
+       {
+         puts ("PI robust mutexes not supported");
+         return 0;
+       }
+      else if (e != 0)
+       {
+         puts ("mutex_init m1 failed");
+         return 1;
+       }
+      pthread_mutex_destroy (&m1);
+    }
+#endif
+
 #ifndef NOT_CONSISTENT
   if (pthread_mutex_init (&m1, &a) != 0)
     {
@@ -236,14 +260,14 @@ do_test (void)
       e = pthread_mutex_unlock (&m1);
       if (e != 0)
        {
-         printf ("%ld: mutex_unlock m1 failed\n", round);
+         printf ("%ld: mutex_unlock m1 failed with %d\n", round, e);
          return 1;
        }
 
       e = pthread_mutex_unlock (&m2);
       if (e != 0)
        {
-         printf ("%ld: mutex_unlock m2 failed\n", round);
+         printf ("%ld: mutex_unlock m2 failed with %d\n", round, e);
          return 1;
        }
 
index 2c5acb4..d0bc91c 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
 
@@ -95,8 +95,25 @@ do_test (void)
       return 1;
     }
 
-  if (pthread_mutex_init (&m, &a) != 0)
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
     {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
+
+  int e;
+  e = pthread_mutex_init (&m, &a);
+  if (e != 0)
+    {
+#ifdef ENABLE_PI
+      if (e == ENOTSUP)
+       {
+         puts ("PI robust mutexes not supported");
+         return 0;
+       }
+#endif
       puts ("mutex_init failed");
       return 1;
     }
@@ -123,7 +140,7 @@ do_test (void)
          return 1;
        }
 
-      int e = pthread_barrier_wait (&b);
+      e = pthread_barrier_wait (&b);
       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
        {
          printf ("parent: barrier_wait failed in round %ld\n", n + 1);
@@ -164,7 +181,7 @@ do_test (void)
        }
     }
 
-  int e = pthread_mutex_lock (&m);
+  e = pthread_mutex_lock (&m);
   if (e == 0)
     {
       puts ("parent: 2nd mutex_lock succeeded");
index 19682e5..9c63625 100644 (file)
@@ -15,7 +15,7 @@ static void prepare (void);
 #define PREPARE(argc, argv) prepare ()
 static int do_test (void);
 #define TEST_FUNCTION do_test ()
-#define TIMEOUT 3
+#define TIMEOUT 5
 #include "../test-skeleton.c"
 
 
@@ -173,6 +173,13 @@ do_test (void)
       puts ("mutexattr_setpshared failed");
       return 1;
     }
+#ifdef ENABLE_PI
+  if (pthread_mutexattr_setprotocol (&ma, PTHREAD_PRIO_INHERIT) != 0)
+    {
+      puts ("pthread_mutexattr_setprotocol failed");
+      return 1;
+    }
+#endif
 
   for (int round = 1; round <= ROUNDS; ++round)
     {
@@ -181,7 +188,11 @@ do_test (void)
          int e = pthread_mutex_init (&map[n], &ma);
          if (e == ENOTSUP)
            {
+#ifdef ENABLE_PI
+             puts ("cannot support pshared robust PI mutexes");
+#else
              puts ("cannot support pshared robust mutexes");
+#endif
              return 0;
            }
          if (e != 0)
diff --git a/nptl/tst-robustpi1.c b/nptl/tst-robustpi1.c
new file mode 100644 (file)
index 0000000..031291b
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust1.c"
diff --git a/nptl/tst-robustpi2.c b/nptl/tst-robustpi2.c
new file mode 100644 (file)
index 0000000..ac411c7
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust2.c"
diff --git a/nptl/tst-robustpi3.c b/nptl/tst-robustpi3.c
new file mode 100644 (file)
index 0000000..7dcf691
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust3.c"
diff --git a/nptl/tst-robustpi4.c b/nptl/tst-robustpi4.c
new file mode 100644 (file)
index 0000000..6c7b0aa
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust4.c"
diff --git a/nptl/tst-robustpi5.c b/nptl/tst-robustpi5.c
new file mode 100644 (file)
index 0000000..a494c33
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust5.c"
diff --git a/nptl/tst-robustpi6.c b/nptl/tst-robustpi6.c
new file mode 100644 (file)
index 0000000..3b1482f
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust6.c"
diff --git a/nptl/tst-robustpi7.c b/nptl/tst-robustpi7.c
new file mode 100644 (file)
index 0000000..f8892f3
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust7.c"
diff --git a/nptl/tst-robustpi8.c b/nptl/tst-robustpi8.c
new file mode 100644 (file)
index 0000000..cbea3d6
--- /dev/null
@@ -0,0 +1,2 @@
+#define ENABLE_PI 1
+#include "tst-robust8.c"
index 9b7a932..3bdf871 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2001, 2002, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2001, 2002, 2005, 2006 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
@@ -56,6 +56,7 @@ __libc_lock_define_initialized (static, lock)
 
 static struct exit_function_list initial;
 struct exit_function_list *__exit_funcs = &initial;
+uint64_t __new_exitfn_called;
 
 struct exit_function *
 __new_exitfn (void)
@@ -111,7 +112,10 @@ __new_exitfn (void)
 
   /* Mark entry as used, but we don't know the flavor now.  */
   if (r != NULL)
-    r->flavor = ef_us;
+    {
+      r->flavor = ef_us;
+      ++__new_exitfn_called;
+    }
 
   __libc_lock_unlock (lock);
 
index 43fcbc4..bb49f36 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1999,2001,2002,2003,2005,2006 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
@@ -31,22 +31,36 @@ __cxa_finalize (void *d)
 {
   struct exit_function_list *funcs;
 
+ restart:
   for (funcs = __exit_funcs; funcs; funcs = funcs->next)
     {
       struct exit_function *f;
 
       for (f = &funcs->fns[funcs->idx - 1]; f >= &funcs->fns[0]; --f)
-       if ((d == NULL || d == f->func.cxa.dso_handle)
-           /* We don't want to run this cleanup more than once.  */
-           && ! atomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
-                                                      ef_cxa))
-         {
-           void (*cxafn) (void *arg, int status) = f->func.cxa.fn;
+       {
+         void (*cxafn) (void *arg, int status);
+         void *cxaarg;
+
+         if ((d == NULL || d == f->func.cxa.dso_handle)
+             /* We don't want to run this cleanup more than once.  */
+             && (cxafn = f->func.cxa.fn,
+                 cxaarg = f->func.cxa.arg,
+                 ! atomic_compare_and_exchange_bool_acq (&f->flavor, ef_free,
+                                                         ef_cxa)))
+           {
+             uint64_t check = __new_exitfn_called;
+
 #ifdef PTR_DEMANGLE
-           PTR_DEMANGLE (cxafn);
+             PTR_DEMANGLE (cxafn);
 #endif
-           cxafn (f->func.cxa.arg, 0);
-         }
+             cxafn (cxaarg, 0);
+
+             /* It is possible that that last exit function registered
+                more exit functions.  Start the loop over.  */
+             if (__builtin_expect (check != __new_exitfn_called, 0))
+               goto restart;
+           }
+       }
     }
 
   /* Remove the registered fork handlers.  We do not have to
index 055506f..779675d 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1996,1997,1999,2001,2002 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1996,1997,1999,2001,2002,2006
+   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
@@ -19,6 +20,7 @@
 #ifndef        _EXIT_H
 #define _EXIT_H 1
 
+#include <stdint.h>
 
 enum
 {
@@ -59,5 +61,6 @@ struct exit_function_list
 extern struct exit_function_list *__exit_funcs attribute_hidden;
 
 extern struct exit_function *__new_exitfn (void);
+extern uint64_t __new_exitfn_called attribute_hidden;
 
 #endif /* exit.h  */
index 9b2e635..6084c38 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 81d9932..1f7ac0f 100644 (file)
@@ -99,7 +99,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 4695d92..1ddb4e3 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 139e3d5..e54f675 100644 (file)
 /* pselect was introduced just after 2.6.16-rc1.  Due to the way the
    kernel versions are advertised we can only rely on 2.6.17 to have
    the code.  */
-#if __LINUX_KERNEL_VERSION >= 0x020611 \
-    && (defined __i386__ || defined __powerpc__)
+#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
 # define __ASSUME_PSELECT      1
 #endif
 
 /* ppoll was introduced just after 2.6.16-rc1.  Due to the way the
    kernel versions are advertised we can only rely on 2.6.17 to have
    the code.  */
-#if __LINUX_KERNEL_VERSION >= 0x020611 \
-    && (defined __i386__ || defined __powerpc__)
+#if __LINUX_KERNEL_VERSION >= 0x020611 && !defined __x86_64__
 # define __ASSUME_PPOLL        1
 #endif
 
 /* The *at syscalls were introduced just after 2.6.16-rc1.  Due to the way the
    kernel versions are advertised we can only rely on 2.6.17 to have
    the code.  */
-#if __LINUX_KERNEL_VERSION >= 0x020611 \
-    && (defined __i386__ || defined __x86_64__)
+#if __LINUX_KERNEL_VERSION >= 0x020611
 # define __ASSUME_ATFCTS       1
 #endif
 
 /* Support for inter-process robust mutexes was added in 2.6.17.  */
-#if __LINUX_KERNEL_VERSION >= 0x020611 \
-    && (defined __i386__ || defined __x86_64__)
+#if __LINUX_KERNEL_VERSION >= 0x020611
 # define __ASSUME_SET_ROBUST_LIST      1
 #endif
+
+/* Support for PI futexes was added in 2.6.18.  */
+#if __LINUX_KERNEL_VERSION >= 0x020612
+# define __ASSUME_FUTEX_LOCK_PI        1
+#endif
index 5d6bb6f..57fc7bd 100644 (file)
@@ -99,7 +99,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 166bae5..e5a917d 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 81d9932..1f7ac0f 100644 (file)
@@ -99,7 +99,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 022f24a..a965d31 100644 (file)
 # define F_SETLKW64    14      /* Set record locking info (blocking).  */
 #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 771de60..4f10f22 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().  */