Updated to fedora-glibc-20070814T0725 fedora-glibc-2_6_90-9
authorjakub <jakub>
Tue, 14 Aug 2007 07:38:35 +0000 (07:38 +0000)
committerjakub <jakub>
Tue, 14 Aug 2007 07:38:35 +0000 (07:38 +0000)
114 files changed:
ChangeLog
csu/libc-start.c
elf/cache.c
elf/dl-dst.h
elf/dl-misc.c
elf/ldconfig.c
elf/readelflib.c
elf/readlib.c
fedora/branch.mk
fedora/glibc.spec.in
include/stdio.h
libio/oldtmpfile.c
manual/stdio.texi
misc/Makefile
misc/Versions
misc/mkdtemp.c
misc/mkostemp.c [new file with mode: 0644]
misc/mkostemp64.c [new file with mode: 0644]
misc/mkstemp.c
misc/mkstemp64.c
misc/mktemp.c
nptl/ChangeLog
nptl/allocatestack.c
nptl/init.c
nptl/pthreadP.h
nptl/pthread_cond_broadcast.c
nptl/pthread_cond_destroy.c
nptl/pthread_cond_signal.c
nptl/pthread_cond_timedwait.c
nptl/pthread_cond_wait.c
nptl/pthread_create.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/unix/sysv/linux/alpha/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/alpha/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S
nptl/sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S
nptl/sysdeps/unix/sysv/linux/i386/i786/Implies [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/i386/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/ia64/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/powerpc/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c [new file with mode: 0644]
nptl/sysdeps/unix/sysv/linux/pthread-pi-defines.sym
nptl/sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c
nptl/sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
nptl/sysdeps/unix/sysv/linux/s390/lowlevellock.h
nptl/sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.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/sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
nptl/sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S
nscd/connections.c
nscd/gai.c
nscd/servicescache.c
nss/Makefile
nss/nss_files/files-XXX.c
nss/nss_files/files-alias.c
nss/nss_files/files-have_o_cloexec.c [new file with mode: 0644]
shadow/lckpwdf.c
stdio-common/tempnam.c
stdio-common/tempname.c
stdio-common/tmpfile.c
stdio-common/tmpfile64.c
stdio-common/tmpnam.c
stdio-common/tmpnam_r.c
stdlib/stdlib.h
sysdeps/generic/ldconfig.h
sysdeps/mach/hurd/bits/ioctls.h
sysdeps/posix/tempname.c
sysdeps/unix/clock_settime.c
sysdeps/unix/sysv/linux/clock_gettime.c
sysdeps/unix/sysv/linux/dl-osinfo.h
sysdeps/unix/sysv/linux/dl-vdso.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/dl-vdso.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/fstatfs64.c
sysdeps/unix/sysv/linux/fxstatat.c
sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h
sysdeps/unix/sysv/linux/if_index.c
sysdeps/unix/sysv/linux/ifaddrs.c
sysdeps/unix/sysv/linux/kernel-features.h
sysdeps/unix/sysv/linux/powerpc/Makefile
sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h
sysdeps/unix/sysv/linux/powerpc/dl-vdso.c [deleted file]
sysdeps/unix/sysv/linux/powerpc/dl-vdso.h [deleted file]
sysdeps/unix/sysv/linux/powerpc/libc-start.c
sysdeps/unix/sysv/linux/ppoll.c
sysdeps/unix/sysv/linux/pselect.c
sysdeps/unix/sysv/linux/s390/s390-32/mmap.S
sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S
sysdeps/unix/sysv/linux/shm_open.c
sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c
sysdeps/unix/sysv/linux/statfs64.c
sysdeps/unix/sysv/linux/x86_64/Makefile
sysdeps/unix/sysv/linux/x86_64/Versions
sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/gettimeofday.S
sysdeps/unix/sysv/linux/x86_64/libc-start.c [new file with mode: 0644]
sysdeps/unix/sysv/linux/x86_64/sysdep.h
sysdeps/unix/sysv/linux/xstatconv.c

index 4f72b85..819ac7e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,189 @@
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/kernel-features.h (__ASSUME_PSELECT,
+       __ASSUME_PPOLL, __ASSUME_ATFCTS, __ASSUME_SET_ROBUST_LIST,
+       __ASSUME_UTIMENSAT, __ASSUME_FALLOCATE): Update per-arch conditions
+       when each feature was introduced.
+
+       * sysdeps/unix/sysv/linux/dl-vdso.c: Don't include dl-hash.h.
+       * sysdeps/unix/sysv/linux/dl-vdso.h: Don't include dl-hash.h if NDEBUG.
+       (CHECK_HASH): New macro.
+       (PREPARE_VERSION): Use it.
+
+       * sysdeps/unix/sysv/linux/pselect.c (__generic_pselect): Only provide
+       prototype if not __ASSUME_PSELECT.
+       * sysdeps/unix/sysv/linux/ppoll.c (__generic_ppoll): Only provide
+       prototype if not __ASSUME_PPOLL.
+
+       * sysdeps/unix/sysv/linux/dl-osinfo.h (ROUND): #undef after use.
+
+       * sysdeps/unix/clock_settime.c (freq, __pthread_clock_settime,
+       hp_timing_settime): Don't define or declare if HANDLED_CPUTIME
+       is defined.
+
+2007-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/libc-start.c
+       (_libc_vdso_platform_setup): If vDSO is not available point
+       __vdso_gettimeofday to the vsyscall.
+       * sysdeps/unix/sysv/linux/x86_64/gettimeofday.S [SHARED]: Use
+       __vdso_gettimeofday instead of vsyscall.
+
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/servicescache.c: Include kernel-features.h.
+       * nscd/gai.c: Likewise.
+       * sysdeps/unix/sysv/linux/statfs64.c: Likewise.
+       * sysdeps/unix/sysv/linux/fstatfs64.c: Likewise.
+       * sysdeps/unix/sysv/linux/fxstatat.c: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/mmap.S: Likewise.
+       * sysdeps/unix/sysv/linux/s390/s390-32/mmap64.S: Likewise.
+       * sysdeps/unix/sysv/linux/xstatconv.c: Likewise.
+       * sysdeps/unix/sysv/linux/if_index.c: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/sparc64/xstat.c: Likewise.
+       * sysdeps/unix/sysv/linux/ifaddrs.c: Likewise.
+
+2007-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-dst.h: No need for _dl_dst_count, _dl_dst_substitute,
+       and _dl_get_origin defines anymore.
+
+       * sysdeps/unix/sysv/linux/clock_gettime.c (maybe_syscall_gettime_cpu):
+       Build fix for systems which might lack POSIX timer support.
+
+       * sysdeps/unix/sysv/linux/x86_64/libc-start.c
+       (_libc_vdso_platform_setup): Mangle function pointers before storing
+       them.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep.h (INLINE_VSYSCALL):
+       Demangle vdso pointer before use.
+       (INTERNAL_VSYSCALL): Likewise.
+
+       * elf/cache.c (primes): Mark as const.
+       Noted by Roland McGrath.
+
+2007-08-01  Andreas Jaeger  <aj@suse.de>
+           Jakub Jelinek  <jakub@redhat.com>
+
+       * elf/ldconfig.c (opt_ignore_aux_cache): Add new option.
+       (options): Add option.
+       (parse_opt): Handle option.
+       (manual_link): Adjust process_file caller.  Call implicit_soname.
+       (search_dir): Formatting.  Use and populate auxiliary cache.
+       (main): Load and save auxiliary cache.
+       * elf/readlib.c (process_file): Add stat_buf argument.  Pass struct
+       stat64 from fstat64 to caller.
+       (implicit_soname): New function.
+       * elf/readelflib.c (process_elf_file): If DT_SONAME is not present,
+       leave *soname as NULL.
+       * elf/cache.c: Include libgen.h.
+       (print_entry, print_cache, compare, save_cache, add_to_cache):
+       Formatting and cleanups.
+       (aux_cache_entry_id, aux_cache_entry, aux_cache_file_entry,
+       aux_cache_file): New structures.
+       (AUX_CACHEMAGIC): Define.
+       (primes): New array.
+       (aux_hash_size, aux_hash): New variables.
+       (aux_cache_entry_id_hash, nextprime, init_aux_cache,
+       search_aux_cache, insert_to_aux_cache, add_to_aux_cache,
+       load_aux_cache, save_aux_cache): New functions.
+       * sysdeps/generic/ldconfig.h (_PATH_LDCONFIG_AUX_CACHE): Define.
+       (init_aux_cache, search_aux_cache, add_to_aux_cache,
+       load_aux_cache, save_aux_cache, implicit_soname): New prototypes.
+       (process_file): Adjust prototype.
+
+2007-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/ia64/bits/sigcontext.h: Include stddef.h
+       with __need_size_t.
+
+2007-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/dl-vdso.c (_dl_vdso_vsym): Expect
+       r_found_version structure as second parameter.
+       * sysdeps/unix/sysv/linux/dl-vdso.h (PREPARE_VERSION): Define.
+       (_dl_vdso_vsym): Change type of second parameter accordingly.
+       * sysdeps/unix/sysv/linux/x86-64/libc-start.c
+       (_libc_vdso_platform_setup): Adjust.
+       * sysdeps/unix/sysv/linux/powerpc/libc-start.c
+       (_libc_vdso_platform_setup): Likewise.
+
+       * sysdeps/unix/sysv/linux/powerpc/dl-vdso.c: Move to...
+       * sysdeps/unix/sysv/linux/dl-vdso.c: ...here.
+       * sysdeps/unix/sysv/linux/powerpc/dl-vdso.h: Move to...
+       * sysdeps/unix/sysv/linux/dl-vdso.h: ...here.
+       * csu/libc-start.c: Pretty printing.
+       Use VDSO_SETUP if defined.
+       * sysdeps/unix/sysv/linux/powerpc/libc-start.c: Define VDSO_SETUP
+       and let generic code call into _libc_vdso_platform_setup.
+       * sysdeps/unix/sysv/linux/x86_64/libc-start.c: New file.
+       * sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h: New file.
+       * sysdeps/unix/sysv/linux/x86_64/sysdep.h: Pretty printing.
+       Define INLINE_VSYSCALL and INTERNAL_VSYSCALL.
+       * sysdeps/unix/sysv/linux/x86_64/Versions: Export __vdso_clock_gettime
+       for GLIBC_PRIVATE.
+       * sysdeps/unix/sysv/linux/x86_64/Makefile [subdir=elf]
+       (sysdep_rountines): Add dl-vdso.
+
+       * sysdeps/unix/sysv/linux/powerpc/Makefile: Use sysdep_routines instead
+       of routines.
+
+       * sysdeps/unix/sysv/linux/powerpc/bits/libc-vdso.h: Add
+       attribute_hidden to __vdso_gettimeofday prototype.
+
+2007-08-12  Roland McGrath  <roland@redhat.com>
+
+       * manual/stdio.texi (Variable Arguments Output): Fix xref to gcc manual.
+       From: Karl Berry <karl@freefriends.org>.
+
+2007-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * elf/dl-misc.c (_dl_sysdep_read_whole_file): We really don't need
+       an atime update for the files we read.
+
 2007-08-10  Ulrich Drepper  <drepper@redhat.com>
 
-       * sysdeps/unix/sysv/linux/shm_open.c (shm_open): Use O_CLOEXEC is
+       * shadow/lckpwdf.c (__lckpwdf): Use O_CLOEXEC if possible.
+
+       * nscd/connections.c: Use O_CLOEXEC if possible.  Use mkostemp
+       instead of mkstemp.
+
+       * misc/Makefile (routines): Add mkostemp and mkostemp64.
+       * misc/Versions: Export mkostemp and mkostemp64 for GLIBC_2.7.
+       * misc/mkostemp.c: New file.
+       * misc/mkostemp64.c: New file.
+       * stdlib/stdlib.h: Declare the new functions.
+       * sysdeps/posix/tempname.c: Add new parameter which is added to
+       the flags for open.  Remove __GT_BIGFILE handling.
+       * stdio-common/tempname.c: Likewise.
+       * include/stdio.h: Adjust __gen_tempname prototype.
+       Renumber __GT_* constants.
+       * libio/oldtmpfile.c: Adjust for __gen_tempname interface change.
+       * misc/mkdtemp.c: Likewise.
+       * misc/mkstemp.c: Likewise.
+       * misc/mkstemp64.c: Likewise.
+       * misc/mktemp.c: Likewise.
+       * stdio-common/tempnam.c: Likewise.
+       * stdio-common/tmpfile.c: Likewise.
+       * stdio-common/tmpfile64.c: Likewise.
+       * stdio-common/tmpnam.c: Likewise.
+       * stdio-common/tmpnam_r.c: Likewise.
+
+2007-08-10  Roland McGrath  <roland@frob.com>
+
+       * sysdeps/mach/hurd/bits/ioctls.h (NLDLY, TABDLY, BSDLY, VTDLY):
+       New macros.
+       (NLDELAY, CRDELAY, TBDELAY, BSDELAY, VTDELAY): Define to those.
+       Reported by Samuel Thibault <samuel.thibault@ens-lyon.org>.
+
+2007-08-10  Ulrich Drepper  <drepper@redhat.com>
+
+       * nss/nss_files/files-XXX.c (internal_setent): Use O_CLOEXEC if
+       possible.
+       * nss/nss_files/files-alias.c (internal_setent): Likewise.
+       * nss/Makefile (libnss_files-routines): Add files-have_o_cloexec.
+       * nss/nss_files/files-have_o_cloexec.c: New file.
+
+       * sysdeps/unix/sysv/linux/shm_open.c (shm_open): Use O_CLOEXEC if
        available.
 
 2007-08-10  Jakub Jelinek  <jakub@redhat.com>
index 0ed9936..d3eadeb 100644 (file)
@@ -138,16 +138,18 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
      functions are using thread functions if these are available and
      we need to setup errno.  */
   __pthread_initialize_minimal ();
-#endif
 
-# ifndef SHARED
   /* Set up the stack checker's canary.  */
   uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard ();
-#  ifdef THREAD_SET_STACK_GUARD
+# ifdef THREAD_SET_STACK_GUARD
   THREAD_SET_STACK_GUARD (stack_chk_guard);
-#  else
+# else
   __stack_chk_guard = stack_chk_guard;
-#  endif
+# endif
+#endif
+
+#ifdef VDSO_SETUP
+  VDSO_SETUP ();
 #endif
 
   /* Register the destructor of the dynamic linker if there is any.  */
index 6dbd5a6..9a600ea 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2003,2005,2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2003,2005,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -20,6 +20,7 @@
 #include <error.h>
 #include <dirent.h>
 #include <inttypes.h>
+#include <libgen.h>
 #include <libintl.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -80,16 +81,16 @@ print_entry (const char *lib, int flag, unsigned int osversion,
       fputs (",x86-64", stdout);
       break;
     case FLAG_S390_LIB64:
-      fputs(",64bit", stdout);
+      fputs (",64bit", stdout);
       break;
     case FLAG_POWERPC_LIB64:
-      fputs(",64bit", stdout);
+      fputs (",64bit", stdout);
       break;
     case FLAG_MIPS64_LIBN32:
-      fputs(",N32", stdout);
+      fputs (",N32", stdout);
       break;
     case FLAG_MIPS64_LIBN64:
-      fputs(",64bit", stdout);
+      fputs (",64bit", stdout);
     case 0:
       break;
     default:
@@ -128,19 +129,11 @@ print_entry (const char *lib, int flag, unsigned int osversion,
 void
 print_cache (const char *cache_name)
 {
-  size_t cache_size;
-  struct stat64 st;
-  int fd;
-  unsigned int i;
-  struct cache_file *cache;
-  struct cache_file_new *cache_new = NULL;
-  const char *cache_data;
-  int format = 0;
-
-  fd = open (cache_name, O_RDONLY);
+  int fd = open (cache_name, O_RDONLY);
   if (fd < 0)
     error (EXIT_FAILURE, errno, _("Can't open cache file %s\n"), cache_name);
 
+  struct stat64 st;
   if (fstat64 (fd, &st) < 0
       /* No need to map the file if it is empty.  */
       || st.st_size == 0)
@@ -149,14 +142,19 @@ print_cache (const char *cache_name)
       return;
     }
 
-  cache = mmap (0, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+  struct cache_file *cache
+    = mmap (NULL, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
   if (cache == MAP_FAILED)
     error (EXIT_FAILURE, errno, _("mmap of cache file failed.\n"));
-  cache_size = st.st_size;
 
+  size_t cache_size = st.st_size;
   if (cache_size < sizeof (struct cache_file))
     error (EXIT_FAILURE, 0, _("File is not a cache file.\n"));
 
+  struct cache_file_new *cache_new = NULL;
+  const char *cache_data;
+  int format = 0;
+
   if (memcmp (cache->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1))
     {
       /* This can only be the new format without the old one.  */
@@ -201,7 +199,7 @@ print_cache (const char *cache_name)
       printf (_("%d libs found in cache `%s'\n"), cache->nlibs, cache_name);
 
       /* Print everything.  */
-      for (i = 0; i < cache->nlibs; i++)
+      for (unsigned int i = 0; i < cache->nlibs; i++)
        print_entry (cache_data + cache->libs[i].key,
                     cache->libs[i].flags, 0, 0,
                     cache_data + cache->libs[i].value);
@@ -212,7 +210,7 @@ print_cache (const char *cache_name)
              cache_new->nlibs, cache_name);
 
       /* Print everything.  */
-      for (i = 0; i < cache_new->nlibs; i++)
+      for (unsigned int i = 0; i < cache_new->nlibs; i++)
        print_entry (cache_data + cache_new->libs[i].key,
                     cache_new->libs[i].flags,
                     cache_new->libs[i].osversion,
@@ -231,15 +229,11 @@ init_cache (void)
   entries = NULL;
 }
 
-
-
-static
-int compare (const struct cache_entry *e1, const struct cache_entry *e2)
+static int
+compare (const struct cache_entry *e1, const struct cache_entry *e2)
 {
-  int res;
-
   /* We need to swap entries here to get the correct sort order.  */
-  res = _dl_cache_libcmp (e2->lib, e1->lib);
+  int res = _dl_cache_libcmp (e2->lib, e1->lib);
   if (res == 0)
     {
       if (e1->flags < e2->flags)
@@ -267,29 +261,19 @@ int compare (const struct cache_entry *e1, const struct cache_entry *e2)
 void
 save_cache (const char *cache_name)
 {
-  struct cache_entry *entry;
-  int fd, idx_old, idx_new;
-  size_t total_strlen, len;
-  char *strings, *str, *temp_name;
-  struct cache_file *file_entries = NULL;
-  struct cache_file_new *file_entries_new = NULL;
-  size_t file_entries_size = 0;
-  size_t file_entries_new_size = 0;
-  unsigned int str_offset;
-  /* Number of cache entries.  */
-  int cache_entry_count = 0;
-  /* Number of normal cache entries.  */
-  int cache_entry_old_count = 0;
-  /* Pad for alignment of cache_file_new.  */
-  size_t pad;
-
   /* The cache entries are sorted already, save them in this order. */
 
   /* Count the length of all strings.  */
   /* The old format doesn't contain hwcap entries and doesn't contain
      libraries in subdirectories with hwcaps entries.  Count therefore
      also all entries with hwcap == 0.  */
-  total_strlen = 0;
+  size_t total_strlen = 0;
+  struct cache_entry *entry;
+  /* Number of cache entries.  */
+  int cache_entry_count = 0;
+  /* Number of normal cache entries.  */
+  int cache_entry_old_count = 0;
+
   for (entry = entries; entry != NULL; entry = entry->next)
     {
       /* Account the final NULs.  */
@@ -300,8 +284,8 @@ save_cache (const char *cache_name)
     }
 
   /* Create the on disk cache structure.  */
-  /* First an array for all strings.  */
-  strings = (char *)xmalloc (total_strlen);
+  struct cache_file *file_entries = NULL;
+  size_t file_entries_size = 0;
 
   if (opt_format != 2)
     {
@@ -315,25 +299,27 @@ save_cache (const char *cache_name)
       /* And the list of all entries in the old format.  */
       file_entries_size = sizeof (struct cache_file)
        + cache_entry_old_count * sizeof (struct file_entry);
-      file_entries = (struct cache_file *) xmalloc (file_entries_size);
+      file_entries = xmalloc (file_entries_size);
 
       /* Fill in the header.  */
-      memset (file_entries, 0, sizeof (struct cache_file));
+      memset (file_entries, '\0', sizeof (struct cache_file));
       memcpy (file_entries->magic, CACHEMAGIC, sizeof CACHEMAGIC - 1);
 
       file_entries->nlibs = cache_entry_old_count;
     }
 
+  struct cache_file_new *file_entries_new = NULL;
+  size_t file_entries_new_size = 0;
+
   if (opt_format != 0)
     {
       /* And the list of all entries in the new format.  */
       file_entries_new_size = sizeof (struct cache_file_new)
        + cache_entry_count * sizeof (struct file_entry_new);
-      file_entries_new =
-       (struct cache_file_new *) xmalloc (file_entries_new_size);
+      file_entries_new = xmalloc (file_entries_new_size);
 
       /* Fill in the header.  */
-      memset (file_entries_new, 0, sizeof (struct cache_file_new));
+      memset (file_entries_new, '\0', sizeof (struct cache_file_new));
       memcpy (file_entries_new->magic, CACHEMAGIC_NEW,
              sizeof CACHEMAGIC_NEW - 1);
       memcpy (file_entries_new->version, CACHE_VERSION,
@@ -343,17 +329,24 @@ save_cache (const char *cache_name)
       file_entries_new->len_strings = total_strlen;
     }
 
-  pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
+  /* Pad for alignment of cache_file_new.  */
+  size_t pad = ALIGN_CACHE (file_entries_size) - file_entries_size;
 
   /* If we have both formats, we hide the new format in the strings
      table, we have to adjust all string indices for this so that
      old libc5/glibc 2 dynamic linkers just ignore them.  */
+  unsigned int str_offset;
   if (opt_format != 0)
     str_offset = file_entries_new_size;
   else
     str_offset = 0;
 
-  str = strings;
+  /* An array for all strings.  */
+  char *strings = xmalloc (total_strlen);
+  char *str = strings;
+  int idx_old;
+  int idx_new;
+
   for (idx_old = 0, idx_new = 0, entry = entries; entry != NULL;
        entry = entry->next, ++idx_new)
     {
@@ -375,21 +368,18 @@ save_cache (const char *cache_name)
          file_entries_new->libs[idx_new].hwcap = entry->hwcap;
          file_entries_new->libs[idx_new].key = str_offset;
        }
-      len = strlen (entry->lib);
-      str = stpcpy (str, entry->lib);
-      /* Account the final NUL.  */
-      ++str;
-      str_offset += len + 1;
+
+      size_t len = strlen (entry->lib) + 1;
+      str = mempcpy (str, entry->lib, len);
+      str_offset += len;
       /* Then the path.  */
       if (opt_format != 2 && entry->hwcap == 0)
        file_entries->libs[idx_old].value = str_offset + pad;
       if (opt_format != 0)
        file_entries_new->libs[idx_new].value = str_offset;
-      len = strlen (entry->path);
-      str = stpcpy (str, entry->path);
-      /* Account the final NUL.  */
-      ++str;
-      str_offset += len + 1;
+      len = strlen (entry->path) + 1;
+      str = mempcpy (str, entry->path, len);
+      str_offset += len;
       /* Ignore entries with hwcap for old format.  */
       if (entry->hwcap == 0)
        ++idx_old;
@@ -403,16 +393,12 @@ save_cache (const char *cache_name)
   /* Write out the cache.  */
 
   /* Write cache first to a temporary file and rename it later.  */
-  temp_name = xmalloc (strlen (cache_name) + 2);
+  char *temp_name = xmalloc (strlen (cache_name) + 2);
   sprintf (temp_name, "%s~", cache_name);
-  /* First remove an old copy if it exists.  */
-  if (unlink (temp_name) && errno != ENOENT)
-    error (EXIT_FAILURE, errno, _("Can't remove old temporary cache file %s"),
-          temp_name);
 
   /* Create file.  */
-  fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
-            S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR);
+  int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
+                S_IRUSR|S_IWUSR);
   if (fd < 0)
     error (EXIT_FAILURE, errno, _("Can't create temporary cache file %s"),
           temp_name);
@@ -439,11 +425,10 @@ save_cache (const char *cache_name)
        error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
     }
 
-  if (write (fd, strings, total_strlen) != (ssize_t) total_strlen)
+  if (write (fd, strings, total_strlen) != (ssize_t) total_strlen
+      || close (fd))
     error (EXIT_FAILURE, errno, _("Writing of cache data failed"));
 
-  close (fd);
-
   /* Make sure user can always read cache file */
   if (chmod (temp_name, S_IROTH|S_IRGRP|S_IRUSR|S_IWUSR))
     error (EXIT_FAILURE, errno,
@@ -463,8 +448,6 @@ save_cache (const char *cache_name)
   while (entries)
     {
       entry = entries;
-      free (entry->path);
-      free (entry->lib);
       entries = entries->next;
       free (entry);
     }
@@ -476,33 +459,29 @@ void
 add_to_cache (const char *path, const char *lib, int flags,
              unsigned int osversion, uint64_t hwcap)
 {
-  struct cache_entry *new_entry, *ptr, *prev;
-  char *full_path;
-  size_t len, i;
-
-  new_entry = (struct cache_entry *) xmalloc (sizeof (struct cache_entry));
-
-  len = strlen (lib) + strlen (path) + 2;
-
-  full_path = (char *) xmalloc (len);
-  snprintf (full_path, len, "%s/%s", path, lib);
-
-  new_entry->lib = xstrdup (lib);
-  new_entry->path = full_path;
+  size_t liblen = strlen (lib) + 1;
+  size_t len = liblen + strlen (path) + 1;
+  struct cache_entry *new_entry
+    = xmalloc (sizeof (struct cache_entry) + liblen + len);
+
+  new_entry->lib = memcpy ((char *) (new_entry + 1), lib, liblen);
+  new_entry->path = new_entry->lib + liblen;
+  snprintf (new_entry->path, len, "%s/%s", path, lib);
   new_entry->flags = flags;
   new_entry->osversion = osversion;
   new_entry->hwcap = hwcap;
   new_entry->bits_hwcap = 0;
 
   /* Count the number of bits set in the masked value.  */
-  for (i = 0; (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
+  for (size_t i = 0;
+       (~((1ULL << i) - 1) & hwcap) != 0 && i < 8 * sizeof (hwcap); ++i)
     if ((hwcap & (1ULL << i)) != 0)
       ++new_entry->bits_hwcap;
 
 
   /* Keep the list sorted - search for right place to insert.  */
-  ptr = entries;
-  prev = entries;
+  struct cache_entry *ptr = entries;
+  struct cache_entry *prev = entries;
   while (ptr != NULL)
     {
       if (compare (ptr, new_entry) > 0)
@@ -522,3 +501,304 @@ add_to_cache (const char *path, const char *lib, int flags,
       prev->next = new_entry;
     }
 }
+
+
+/* Auxiliary cache.  */
+
+struct aux_cache_entry_id
+{
+  uint64_t ino;
+  uint64_t ctime;
+  uint64_t size;
+  uint64_t dev;
+};
+
+struct aux_cache_entry
+{
+  struct aux_cache_entry_id id;
+  int flags;
+  unsigned int osversion;
+  int used;
+  char *soname;
+  struct aux_cache_entry *next;
+};
+
+#define AUX_CACHEMAGIC         "glibc-ld.so.auxcache-1.0"
+
+struct aux_cache_file_entry
+{
+  struct aux_cache_entry_id id;        /* Unique id of entry.  */
+  int32_t flags;               /* This is 1 for an ELF library.  */
+  uint32_t soname;             /* String table indice.  */
+  uint32_t osversion;          /* Required OS version.  */
+  int32_t pad;
+};
+
+/* ldconfig maintains an auxiliary cache file that allows
+   only reading those libraries that have changed since the last iteration.
+   For this for each library some information is cached in the auxiliary
+   cache.  */
+struct aux_cache_file
+{
+  char magic[sizeof AUX_CACHEMAGIC - 1];
+  uint32_t nlibs;              /* Number of entries.  */
+  uint32_t len_strings;                /* Size of string table. */
+  struct aux_cache_file_entry libs[0]; /* Entries describing libraries.  */
+  /* After this the string table of size len_strings is found. */
+};
+
+static const unsigned int primes[] =
+{
+  1021, 2039, 4093, 8191, 16381, 32749, 65521, 131071, 262139,
+  524287, 1048573, 2097143, 4194301, 8388593, 16777213, 33554393,
+  67108859, 134217689, 268435399, 536870909, 1073741789, 2147483647
+};
+
+static size_t aux_hash_size;
+static struct aux_cache_entry **aux_hash;
+
+/* Simplistic hash function for aux_cache_entry_id.  */
+static unsigned int
+aux_cache_entry_id_hash (struct aux_cache_entry_id *id)
+{
+  uint64_t ret = ((id->ino * 11 + id->ctime) * 11 + id->size) * 11 + id->dev;
+  return ret ^ (ret >> 32);
+}
+
+static size_t nextprime (size_t x)
+{
+  for (unsigned int i = 0; i < sizeof (primes) / sizeof (primes[0]); ++i)
+    if (primes[i] >= x)
+      return primes[i];
+  return x;
+}
+
+void
+init_aux_cache (void)
+{
+  aux_hash_size = primes[3];
+  aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
+}
+
+int
+search_aux_cache (struct stat64 *stat_buf, int *flags,
+                 unsigned int *osversion, char **soname)
+{
+  struct aux_cache_entry_id id;
+  id.ino = (uint64_t) stat_buf->st_ino;
+  id.ctime = (uint64_t) stat_buf->st_ctime;
+  id.size = (uint64_t) stat_buf->st_size;
+  id.dev = (uint64_t) stat_buf->st_dev;
+
+  unsigned int hash = aux_cache_entry_id_hash (&id);
+  struct aux_cache_entry *entry;
+  for (entry = aux_hash[hash % aux_hash_size]; entry; entry = entry->next)
+    if (id.ino == entry->id.ino
+       && id.ctime == entry->id.ctime
+       && id.size == entry->id.size
+       && id.dev == entry->id.dev)
+      {
+       *flags = entry->flags;
+       *osversion = entry->osversion;
+       if (entry->soname != NULL)
+         *soname = xstrdup (entry->soname);
+       else
+         *soname = NULL;
+       entry->used = 1;
+       return 1;
+      }
+
+  return 0;
+}
+
+static void
+insert_to_aux_cache (struct aux_cache_entry_id *id, int flags,
+                    unsigned int osversion, const char *soname, int used)
+{
+  size_t hash = aux_cache_entry_id_hash (id) % aux_hash_size;
+  struct aux_cache_entry *entry;
+  for (entry = aux_hash[hash]; entry; entry = entry->next)
+    if (id->ino == entry->id.ino
+       && id->ctime == entry->id.ctime
+       && id->size == entry->id.size
+       && id->dev == entry->id.dev)
+      abort ();
+
+  size_t len = soname ? strlen (soname) + 1 : 0;
+  entry = xmalloc (sizeof (struct aux_cache_entry) + len);
+  entry->id = *id;
+  entry->flags = flags;
+  entry->osversion = osversion;
+  entry->used = used;
+  if (soname != NULL)
+    entry->soname = memcpy ((char *) (entry + 1), soname, len);
+  else
+    entry->soname = NULL;
+  entry->next = aux_hash[hash];
+  aux_hash[hash] = entry;
+}
+
+void
+add_to_aux_cache (struct stat64 *stat_buf, int flags,
+                 unsigned int osversion, const char *soname)
+{
+  struct aux_cache_entry_id id;
+  id.ino = (uint64_t) stat_buf->st_ino;
+  id.ctime = (uint64_t) stat_buf->st_ctime;
+  id.size = (uint64_t) stat_buf->st_size;
+  id.dev = (uint64_t) stat_buf->st_dev;
+  insert_to_aux_cache (&id, flags, osversion, soname, 1);
+}
+
+/* Load auxiliary cache to search for unchanged entries.   */
+void
+load_aux_cache (const char *aux_cache_name)
+{
+  int fd = open (aux_cache_name, O_RDONLY);
+  if (fd < 0)
+    {
+      init_aux_cache ();
+      return;
+    }
+
+  struct stat64 st;
+  if (fstat64 (fd, &st) < 0 || st.st_size < sizeof (struct aux_cache_file))
+    {
+      close (fd);
+      init_aux_cache ();
+      return;
+    }
+
+  size_t aux_cache_size = st.st_size;
+  struct aux_cache_file *aux_cache
+    = mmap (NULL, aux_cache_size, PROT_READ, MAP_PRIVATE, fd, 0);
+  if (aux_cache == MAP_FAILED
+      || aux_cache_size < sizeof (struct aux_cache_file)
+      || memcmp (aux_cache->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1)
+      || aux_cache->nlibs < 0
+      || aux_cache->nlibs >= aux_cache_size)
+    {
+      close (fd);
+      init_aux_cache ();
+      return;
+    }
+
+  aux_hash_size = nextprime (aux_cache->nlibs);
+  aux_hash = xcalloc (aux_hash_size, sizeof (struct aux_cache_entry *));
+
+  const char *aux_cache_data
+    = (const char *) &aux_cache->libs[aux_cache->nlibs];
+  for (unsigned int i = 0; i < aux_cache->nlibs; ++i)
+    insert_to_aux_cache (&aux_cache->libs[i].id,
+                        aux_cache->libs[i].flags,
+                        aux_cache->libs[i].osversion,
+                        aux_cache->libs[i].soname == 0
+                        ? NULL : aux_cache_data + aux_cache->libs[i].soname,
+                        0);
+
+  munmap (aux_cache, aux_cache_size);
+  close (fd);
+}
+
+/* Save the contents of the auxiliary cache.  */
+void
+save_aux_cache (const char *aux_cache_name)
+{
+  /* Count the length of all sonames.  We start with empty string.  */
+  size_t total_strlen = 1;
+  /* Number of cache entries.  */
+  int cache_entry_count = 0;
+
+  for (size_t i = 0; i < aux_hash_size; ++i)
+    for (struct aux_cache_entry *entry = aux_hash[i];
+        entry != NULL; entry = entry->next)
+      if (entry->used)
+       {
+         ++cache_entry_count;
+         if (entry->soname != NULL)
+           total_strlen += strlen (entry->soname) + 1;
+       }
+
+  /* Auxiliary cache.  */
+  size_t file_entries_size
+    = sizeof (struct aux_cache_file)
+      + cache_entry_count * sizeof (struct aux_cache_file_entry);
+  struct aux_cache_file *file_entries
+    = xmalloc (file_entries_size + total_strlen);
+
+  /* Fill in the header of the auxiliary cache.  */
+  memset (file_entries, '\0', sizeof (struct aux_cache_file));
+  memcpy (file_entries->magic, AUX_CACHEMAGIC, sizeof AUX_CACHEMAGIC - 1);
+
+  file_entries->nlibs = cache_entry_count;
+  file_entries->len_strings = total_strlen;
+
+  /* Initial String offset for auxiliary cache is always after the
+     special empty string.  */
+  unsigned int str_offset = 1;
+
+  /* An array for all strings.  */
+  char *str = (char *) file_entries + file_entries_size;
+  *str++ = '\0';
+
+  size_t idx = 0;
+  for (size_t i = 0; i < aux_hash_size; ++i)
+    for (struct aux_cache_entry *entry = aux_hash[i];
+        entry != NULL; entry = entry->next)
+      if (entry->used)
+       {
+         file_entries->libs[idx].id = entry->id;
+         file_entries->libs[idx].flags = entry->flags;
+         if (entry->soname == NULL)
+           file_entries->libs[idx].soname = 0;
+         else
+           {
+             file_entries->libs[idx].soname = str_offset;
+
+             size_t len = strlen (entry->soname) + 1;
+             str = mempcpy (str, entry->soname, len);
+             str_offset += len;
+           }
+         file_entries->libs[idx].osversion = entry->osversion;
+         file_entries->libs[idx++].pad = 0;
+       }
+
+  /* Write out auxiliary cache file.  */
+  /* Write auxiliary cache first to a temporary file and rename it later.  */
+
+  char *temp_name = xmalloc (strlen (aux_cache_name) + 2);
+  sprintf (temp_name, "%s~", aux_cache_name);
+
+  /* Check that directory exists and create if needed.  */
+  char *dir = strdupa (aux_cache_name);
+  dir = dirname (dir);
+
+  struct stat64 st;
+  if (stat64 (dir, &st) < 0)
+    {
+      if (mkdir (dir, 0700) < 0)
+       goto out_fail;
+    }
+
+  /* Create file.  */
+  int fd = open (temp_name, O_CREAT|O_WRONLY|O_TRUNC|O_NOFOLLOW,
+                S_IRUSR|S_IWUSR);
+  if (fd < 0)
+    goto out_fail;
+
+  if (write (fd, file_entries, file_entries_size + total_strlen)
+      != (ssize_t) (file_entries_size + total_strlen)
+      || close (fd))
+    {
+      unlink (temp_name);
+      goto out_fail;
+    }
+
+  /* Move temporary to its final location.  */
+  if (rename (temp_name, aux_cache_name))
+    unlink (temp_name);
+
+out_fail:
+  /* Free allocated memory.  */
+  free (file_entries);
+}
index 175b7cd..76076a6 100644 (file)
@@ -29,9 +29,6 @@
       __cnt = _dl_dst_count (__sf, is_path);                         \
                                                                              \
     __cnt; })
-#ifndef IS_IN_rtld
-# define _dl_dst_count GLRO(dl_dst_count)
-#endif
 
 
 /* Guess from the number of DSTs the length of the result string.  */
@@ -79,8 +76,3 @@
     }                                                                        \
   else
 #endif
-
-#ifndef IS_IN_rtld
-# define _dl_get_origin GLRO(dl_get_origin)
-# define _dl_dst_substitute GLRO(dl_dst_substitute)
-#endif
index 6da1e2e..41da98d 100644 (file)
@@ -1,5 +1,5 @@
 /* Miscellaneous support functions for dynamic linker
-   Copyright (C) 1997-2002, 2003, 2004, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1997-2004, 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
@@ -55,7 +55,11 @@ _dl_sysdep_read_whole_file (const char *file, size_t *sizep, int prot)
 {
   void *result = MAP_FAILED;
   struct stat64 st;
-  int fd = __open (file, O_RDONLY);
+  int oflags = O_RDONLY;
+#ifdef O_NOATIME
+  oflags |= O_NOATIME;
+#endif
+  int fd = __open (file, oflags);
   if (fd >= 0)
     {
       if (__fxstat64 (_STAT_VER, fd, &st) >= 0)
index 7692e3a..cb1851e 100644 (file)
@@ -112,6 +112,9 @@ static char *opt_chroot;
 /* Manually link given shared libraries.  */
 static int opt_manual_link;
 
+/* Should we ignore an old auxiliary cache file?  */
+static int opt_ignore_aux_cache;
+
 /* Cache file to use.  */
 static char *cache_file;
 
@@ -142,6 +145,7 @@ static const struct argp_option options[] =
   { NULL, 'n', NULL, 0, N_("Only process directories specified on the command line.  Don't build cache."), 0},
   { NULL, 'l', NULL, 0, N_("Manually link individual libraries."), 0},
   { "format", 'c', N_("FORMAT"), 0, N_("Format to use: new, old or compat (default)"), 0},
+  { "ignore-aux-cache", 'i', NULL, 0, N_("Ignore auxiliary cache file"), 0},
   { NULL, 0, NULL, 0, NULL, 0 }
 };
 
@@ -238,10 +242,15 @@ parse_opt (int key, char *arg, struct argp_state *state)
     {
     case 'C':
       cache_file = arg;
+      /* Ignore auxiliary cache since we use non-standard cache.  */
+      opt_ignore_aux_cache = 1;
       break;
     case 'f':
       config_file = arg;
       break;
+    case 'i':
+      opt_ignore_aux_cache = 1;
+      break;
     case 'l':
       opt_manual_link = 1;
       break;
@@ -518,7 +527,7 @@ manual_link (char *library)
   if (libname)
     {
       /* Successfully split names.  Check if path is just "/" to avoid
-         an empty path.  */
+        an empty path.  */
       if (libname == path)
        {
          libname = library + 1;
@@ -572,14 +581,17 @@ manual_link (char *library)
       free (path);
       return;
     }
+
   if (process_file (real_library, library, libname, &flag, &osversion,
-                   &soname, 0))
+                   &soname, 0, &stat_buf))
     {
       error (0, 0, _("No link created since soname could not be found for %s"),
             library);
       free (path);
       return;
     }
+  if (soname == NULL)
+    soname = implicit_soname (libname, flag);
   create_links (real_path, path, libname, soname);
   free (soname);
   free (path);
@@ -625,23 +637,7 @@ struct dlib_entry
 static void
 search_dir (const struct dir_entry *entry)
 {
-  DIR *dir;
-  struct dirent64 *direntry;
-  char *file_name, *dir_name, *real_file_name, *real_name;
-  int file_name_len, real_file_name_len, len;
-  char *soname;
-  struct dlib_entry *dlibs;
-  struct dlib_entry *dlib_ptr;
-  struct stat64 lstat_buf, stat_buf;
-  int is_link, is_dir;
   uint64_t hwcap = path_hwcap (entry->path);
-  unsigned int osversion;
-
-  file_name_len = PATH_MAX;
-  file_name = alloca (file_name_len);
-
-  dlibs = NULL;
-
   if (opt_verbose)
     {
       if (hwcap != 0)
@@ -650,6 +646,11 @@ search_dir (const struct dir_entry *entry)
        printf ("%s:\n", entry->path);
     }
 
+  char *dir_name;
+  char *real_file_name;
+  size_t real_file_name_len;
+  size_t file_name_len = PATH_MAX;
+  char *file_name = alloca (file_name_len);
   if (opt_chroot)
     {
       dir_name = chroot_canon (opt_chroot, entry->path);
@@ -663,6 +664,7 @@ search_dir (const struct dir_entry *entry)
       real_file_name = file_name;
     }
 
+  DIR *dir;
   if (dir_name == NULL || (dir = opendir (dir_name)) == NULL)
     {
       if (opt_verbose)
@@ -672,6 +674,8 @@ search_dir (const struct dir_entry *entry)
       return;
     }
 
+  struct dirent64 *direntry;
+  struct dlib_entry *dlibs = NULL;
   while ((direntry = readdir64 (dir)) != NULL)
     {
       int flag;
@@ -695,7 +699,8 @@ search_dir (const struct dir_entry *entry)
 #endif
              !is_hwcap_platform (direntry->d_name)))
        continue;
-      len = strlen (direntry->d_name);
+
+      size_t len = strlen (direntry->d_name);
       /* Skip temporary files created by the prelink program.  Files with
         names like these are never really DSOs we want to look at.  */
       if (len >= sizeof (".#prelink#") - 1)
@@ -727,7 +732,10 @@ search_dir (const struct dir_entry *entry)
            }
          sprintf (real_file_name, "%s/%s", dir_name, direntry->d_name);
        }
+
+      struct stat64 lstat_buf;
 #ifdef _DIRENT_HAVE_D_TYPE
+      /* We optimize and try to do the lstat call only if needed.  */
       if (direntry->d_type != DT_UNKNOWN)
        lstat_buf.st_mode = DTTOIF (direntry->d_type);
       else
@@ -738,9 +746,11 @@ search_dir (const struct dir_entry *entry)
            continue;
          }
 
-      is_link = S_ISLNK (lstat_buf.st_mode);
+      struct stat64 stat_buf;
+      int is_dir;
+      int is_link = S_ISLNK (lstat_buf.st_mode);
       if (is_link)
-        {
+       {
          /* In case of symlink, we check if the symlink refers to
             a directory. */
          if (__builtin_expect (stat64 (real_file_name, &stat_buf), 0))
@@ -754,6 +764,12 @@ search_dir (const struct dir_entry *entry)
              continue;
            }
          is_dir = S_ISDIR (stat_buf.st_mode);
+
+         /* lstat_buf is later stored, update contents.  */
+         lstat_buf.st_dev = stat_buf.st_dev;
+         lstat_buf.st_ino = stat_buf.st_ino;
+         lstat_buf.st_size = stat_buf.st_size;
+         lstat_buf.st_ctime = stat_buf.st_ctime;
        }
       else
        is_dir = S_ISDIR (lstat_buf.st_mode);
@@ -767,36 +783,28 @@ search_dir (const struct dir_entry *entry)
          new_entry->path = xstrdup (file_name);
          new_entry->flag = entry->flag;
          new_entry->next = NULL;
-         if (is_link)
+#ifdef _DIRENT_HAVE_D_TYPE
+         /* We have filled in lstat only #ifndef
+            _DIRENT_HAVE_D_TYPE.  Fill it in if needed.  */
+         if (!is_link
+             && direntry->d_type != DT_UNKNOWN
+             && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
            {
-             new_entry->ino = stat_buf.st_ino;
-             new_entry->dev = stat_buf.st_dev;
+             error (0, errno, _("Cannot lstat %s"), file_name);
+             free (new_entry->path);
+             free (new_entry);
+             continue;
            }
-         else
-           {
-#ifdef _DIRENT_HAVE_D_TYPE
-             /* We have filled in lstat only #ifndef
-                _DIRENT_HAVE_D_TYPE.  Fill it in if needed.  */
-             if (direntry->d_type != DT_UNKNOWN
-                 && __builtin_expect (lstat64 (real_file_name, &lstat_buf),
-                                      0))
-               {
-                 error (0, errno, _("Cannot lstat %s"), file_name);
-                 free (new_entry->path);
-                 free (new_entry);
-                 continue;
-               }
 #endif
-
-             new_entry->ino = lstat_buf.st_ino;
-             new_entry->dev = lstat_buf.st_dev;
-           }
+         new_entry->ino = lstat_buf.st_ino;
+         new_entry->dev = lstat_buf.st_dev;
          add_single_dir (new_entry, 0);
          continue;
        }
       else if (!S_ISREG (lstat_buf.st_mode) && !is_link)
        continue;
 
+      char *real_name;
       if (opt_chroot && is_link)
        {
          real_name = chroot_canon (opt_chroot, file_name);
@@ -810,14 +818,36 @@ search_dir (const struct dir_entry *entry)
       else
        real_name = real_file_name;
 
-      if (process_file (real_name, file_name, direntry->d_name, &flag,
-                       &osversion, &soname, is_link))
+#ifdef _DIRENT_HAVE_D_TYPE
+      /* Call lstat64 if not done yet.  */
+      if (!is_link
+         && direntry->d_type != DT_UNKNOWN
+         && __builtin_expect (lstat64 (real_file_name, &lstat_buf), 0))
        {
-         if (real_name != real_file_name)
-           free (real_name);
+         error (0, errno, _("Cannot lstat %s"), file_name);
          continue;
        }
+#endif
+
+      /* First search whether the auxiliary cache contains this
+        library already and it's not changed.  */
+      char *soname;
+      unsigned int osversion;
+      if (!search_aux_cache (&lstat_buf, &flag, &osversion, &soname))
+       {
+         if (process_file (real_name, file_name, direntry->d_name, &flag,
+                           &osversion, &soname, is_link, &lstat_buf))
+           {
+             if (real_name != real_file_name)
+               free (real_name);
+             continue;
+           }
+         else if (opt_build_cache)
+           add_to_aux_cache (&lstat_buf, flag, osversion, soname);
+       }
 
+      if (soname == NULL)
+       soname = implicit_soname (direntry->d_name, flag);
 
       /* A link may just point to itself.  */
       if (is_link)
@@ -834,7 +864,7 @@ search_dir (const struct dir_entry *entry)
                  || strncmp (real_base_name, soname, len) != 0)
                is_link = 0;
            }
-        }
+       }
 
       if (real_name != real_file_name)
        free (real_name);
@@ -849,6 +879,7 @@ search_dir (const struct dir_entry *entry)
          && (entry->flag == FLAG_ELF_LIBC5
              || entry->flag == FLAG_ELF_LIBC6))
        flag = entry->flag;
+
       /* Some sanity checks to print warnings.  */
       if (opt_verbose)
        {
@@ -864,6 +895,7 @@ search_dir (const struct dir_entry *entry)
        }
 
       /* Add library to list.  */
+      struct dlib_entry *dlib_ptr;
       for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
        {
          /* Is soname already in list?  */
@@ -888,12 +920,13 @@ search_dir (const struct dir_entry *entry)
                        dlib_ptr->flag = flag;
                      else
                        error (0, 0, _("libraries %s and %s in directory %s have same soname but different type."),
-                              dlib_ptr->name, direntry->d_name, entry->path);
+                              dlib_ptr->name, direntry->d_name,
+                              entry->path);
                    }
                  free (dlib_ptr->name);
-                 dlib_ptr->osversion = osversion;
                  dlib_ptr->name = xstrdup (direntry->d_name);
                  dlib_ptr->is_link = is_link;
+                 dlib_ptr->osversion = osversion;
                }
              /* Don't add this library, abort loop.  */
              /* Also free soname, since it's dynamically allocated.  */
@@ -906,10 +939,10 @@ search_dir (const struct dir_entry *entry)
        {
          dlib_ptr = (struct dlib_entry *)xmalloc (sizeof (struct dlib_entry));
          dlib_ptr->name = xstrdup (direntry->d_name);
-         dlib_ptr->flag = flag;
-         dlib_ptr->osversion = osversion;
          dlib_ptr->soname = soname;
+         dlib_ptr->flag = flag;
          dlib_ptr->is_link = is_link;
+         dlib_ptr->osversion = osversion;
          /* Add at head of list.  */
          dlib_ptr->next = dlibs;
          dlibs = dlib_ptr;
@@ -920,6 +953,7 @@ search_dir (const struct dir_entry *entry)
 
   /* Now dlibs contains a list of all libs - add those to the cache
      and created all symbolic links.  */
+  struct dlib_entry *dlib_ptr;
   for (dlib_ptr = dlibs; dlib_ptr != NULL; dlib_ptr = dlib_ptr->next)
     {
       /* Don't create links to links.  */
@@ -1257,7 +1291,7 @@ main (int argc, char **argv)
   if (opt_chroot)
     {
       /* Canonicalize the directory name of cache_file, not cache_file,
-         because we'll rename a temporary cache file to it.  */
+        because we'll rename a temporary cache file to it.  */
       char *p = strrchr (cache_file, '/');
       char *canon = chroot_canon (opt_chroot,
                                  p ? (*p = '\0', cache_file) : "/");
@@ -1306,10 +1340,18 @@ main (int argc, char **argv)
       add_arch_dirs (config_file);
     }
 
+  if (! opt_ignore_aux_cache)
+    load_aux_cache (_PATH_LDCONFIG_AUX_CACHE);
+  else
+    init_aux_cache ();
+
   search_dirs ();
 
   if (opt_build_cache)
-    save_cache (cache_file);
+    {
+      save_cache (cache_file);
+      save_aux_cache (_PATH_LDCONFIG_AUX_CACHE);
+    }
 
   return 0;
 }
index ea92d89..b8f677a 100644 (file)
@@ -231,11 +231,5 @@ process_elf_file (const char *file_name, const char *lib, int *flag,
        }
     }
 
-  /* We reach this point only if the file doesn't contain a DT_SONAME
-     or if we can't classify the library.  If it doesn't have a
-     soname, return the name of the library.  */
-  if (*soname == NULL)
-    *soname = xstrdup (lib);
-
   return 0;
 }
index a3278d9..eb64a79 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999 and
                  Jakub Jelinek <jakub@redhat.com>, 1999.
@@ -69,7 +69,7 @@ static struct known_names known_libs[] =
 int
 process_file (const char *real_file_name, const char *file_name,
              const char *lib, int *flag, unsigned int *osversion,
-             char **soname, int is_link)
+             char **soname, int is_link, struct stat64 *stat_buf)
 {
   FILE *file;
   struct stat64 statbuf;
@@ -135,7 +135,7 @@ process_file (const char *real_file_name, const char *file_name,
       )
     {
       /* Aout files don't have a soname, just return the name
-         including the major number.  */
+        including the major number.  */
       char *copy, *major, *dot;
       copy = xstrdup (lib);
       major = strstr (copy, ".so.");
@@ -175,8 +175,31 @@ process_file (const char *real_file_name, const char *file_name,
   munmap (file_contents, statbuf.st_size);
   fclose (file);
 
+  *stat_buf = statbuf;
   return ret;
 }
 
+/* Returns made up soname if lib doesn't have explicit DT_SONAME.  */
+
+char *
+implicit_soname (const char *lib, int flag)
+{
+  char *soname = xstrdup (lib);
+
+  if ((flag & FLAG_TYPE_MASK) != FLAG_LIBC4)
+    return soname;
+
+  /* Aout files don't have a soname, just return the name
+     including the major number.  */
+  char *major = strstr (soname, ".so.");
+  if (major)
+    {
+      char *dot = strstr (major + 4, ".");
+      if (dot)
+       *dot = '\0';
+    }
+  return soname;
+}
+
 /* Get architecture specific version of process_elf_file.  */
 #include <readelflib.c>
index ad46076..22e86bb 100644 (file)
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-f8
-fedora-sync-date := 2007-08-10 21:52 UTC
-fedora-sync-tag := fedora-glibc-20070810T2152
+fedora-sync-date := 2007-08-14 07:25 UTC
+fedora-sync-tag := fedora-glibc-20070814T0725
index a696bbb..535cfc6 100644 (file)
@@ -1,4 +1,4 @@
-%define glibcrelease 7
+%define glibcrelease 9
 %define run_glibc_tests 1
 %define auxarches i586 i686 athlon sparcv9 alphaev6
 %define xenarches i686 athlon
@@ -1000,11 +1000,17 @@ rm -f *.filelist*
 %endif
 
 %changelog
-* Fri Aug 10 2007 Roland McGrath <roland@redhat.com> 2.6.90-7
+* Tue Aug 14 2007 Jakub Jelinek <jakub@redhat.com> 2.6.90-9
+- private futex even for mutexes and condvars
+- some further O_CLOEXEC changes
+- use vDSO on x86_64 if available
+- ia64 build fixes (#251983)
+
+* Fri Aug 10 2007 Roland McGrath <roland@redhat.com> 2.6.90-8
 - update to trunk
   - fix missing strtold_l export on ppc64
 
-* Thu Aug  9 2007 Roland McGrath <roland@redhat.com> 2.6.90-5
+* Thu Aug  9 2007 Roland McGrath <roland@redhat.com> 2.6.90-6
 - update to trunk
   - fix local PLT regressions
 - spec file revamp for new find-debuginfo.sh
index 6fe881c..748523d 100644 (file)
@@ -54,12 +54,11 @@ extern int __path_search (char *__tmpl, size_t __tmpl_len,
                          __const char *__dir, __const char *__pfx,
                          int __try_tempdir);
 
-extern int __gen_tempname (char *__tmpl, int __kind);
+extern int __gen_tempname (char *__tmpl, int __flags, int __kind);
 /* The __kind argument to __gen_tempname may be one of: */
 #  define __GT_FILE    0       /* create a file */
-#  define __GT_BIGFILE 1       /* create a file, using open64 */
-#  define __GT_DIR     2       /* create a directory */
-#  define __GT_NOCREATE        3       /* just find a name not currently in use */
+#  define __GT_DIR     1       /* create a directory */
+#  define __GT_NOCREATE        2       /* just find a name not currently in use */
 
 /* Print out MESSAGE on the error output and abort.  */
 extern void __libc_fatal (__const char *__message)
index 8631d48..d85467a 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 1991,1993,1996-2000,2003,2004 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-2000,2003,2004,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
@@ -38,7 +39,7 @@ __old_tmpfile (void)
 
   if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
     return NULL;
-  fd = __gen_tempname (buf, __GT_FILE);
+  fd = __gen_tempname (buf, 0, __GT_FILE);
   if (fd < 0)
     return NULL;
 
index 30a6e6e..a39262c 100644 (file)
@@ -2456,9 +2456,8 @@ For example:
 @end smallexample
 
 @noindent
-@xref{Macro Varargs, , Macros with Variable Numbers of Arguments,
-gcc.info, Using GNU CC}, for details.  But this is limited to macros,
-and does not apply to real functions at all.
+@xref{Variadic Macros,,, cpp, The C preprocessor}, for details.
+But this is limited to macros, and does not apply to real functions at all.
 
 Before calling @code{vprintf} or the other functions listed in this
 section, you @emph{must} call @code{va_start} (@pxref{Variadic
index 9eac1b6..a9709f9 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+# Copyright (C) 1991-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
@@ -45,6 +45,7 @@ routines := brk sbrk sstk ioctl \
            gethostid sethostid \
            revoke vhangup \
            swapon swapoff mktemp mkstemp mkstemp64 mkdtemp \
+           mkostemp mkostemp64 \
            ualarm usleep \
            gtty stty \
            ptrace \
index fdf2d9d..b182f12 100644 (file)
@@ -134,4 +134,7 @@ libc {
     futimesat;
     __syslog_chk; __vsyslog_chk;
   }
+  GLIBC_2.7 {
+    mkostemp; mkostemp64;
+  }
 }
index abb9a35..7cd3a44 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 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
@@ -28,7 +28,7 @@ char *
 mkdtemp (template)
      char *template;
 {
-  if (__gen_tempname (template, __GT_DIR))
+  if (__gen_tempname (template, 0, __GT_DIR))
     return NULL;
   else
     return template;
diff --git a/misc/mkostemp.c b/misc/mkostemp.c
new file mode 100644 (file)
index 0000000..372e4f3
--- /dev/null
@@ -0,0 +1,36 @@
+/* Copyright (C) 1998, 1999, 2001, 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifndef __GT_FILE
+# define __GT_FILE 0
+#endif
+
+/* Generate a unique temporary file name from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the filename unique.
+   Then open the file and return a fd. */
+int
+mkostemp (template, flags)
+     char *template;
+     int flags;
+{
+  return __gen_tempname (template, flags, __GT_FILE);
+}
diff --git a/misc/mkostemp64.c b/misc/mkostemp64.c
new file mode 100644 (file)
index 0000000..2ae7309
--- /dev/null
@@ -0,0 +1,33 @@
+/* Copyright (C) 2000, 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* Generate a unique temporary file name from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the filename unique.
+   Then open the file and return a fd. */
+int
+mkostemp64 (template, flags)
+     char *template;
+     int flags;
+{
+  return __gen_tempname (template, flags | O_LARGEFILE, __GT_FILE);
+}
index ff0ffa2..d3edca0 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2001, 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
@@ -31,5 +31,5 @@ int
 mkstemp (template)
      char *template;
 {
-  return __gen_tempname (template, __GT_FILE);
+  return __gen_tempname (template, 0, __GT_FILE);
 }
index 93c2a3e..400bf47 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 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
@@ -16,6 +16,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <stdlib.h>
 
@@ -27,5 +28,5 @@ int
 mkstemp64 (template)
      char *template;
 {
-  return __gen_tempname (template, __GT_BIGFILE);
+  return __gen_tempname (template, O_LARGEFILE, __GT_FILE);
 }
index 20dfc74..f600d7e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
+/* Copyright (C) 1998, 1999, 2000, 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
@@ -26,7 +26,7 @@ char *
 mktemp (template)
      char *template;
 {
-  if (__gen_tempname (template, __GT_NOCREATE) < 0)
+  if (__gen_tempname (template, 0, __GT_NOCREATE) < 0)
     /* We return the null string if we can't find a unique file name.  */
     template[0] = '\0';
 
index 2e85043..f46f53a 100644 (file)
@@ -1,3 +1,195 @@
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/lowlevellock.h (__lll_private_flag):
+       Fix a pasto.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+       FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+       Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_signal.S
+       (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+       FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_wait.S: Include
+       kernel-features.h.
+       (__pthread_cond_wait, __condvar_w_cleanup): Pass LLL_PRIVATE to
+       lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+       process private.  Switch DW_CFA_advance_loc1 and some
+       DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait, __condvar_tw_cleanup): Pass LLL_PRIVATE to
+       lll_* and or FUTEX_PRIVATE_FLAG into SYS_futex op if cv is
+       process private.  Switch DW_CFA_advance_loc{1,2} and some
+       DW_CFA_advance_loc .eh_frame opcodes to DW_CFA_advance_loc4.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Use
+       #ifdef __ASSUME_PRIVATE_FUTEX instead of #if __ASSUME_PRIVATE_FUTEX.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Compare %r8 instead of
+       dep_mutex-cond_*(%rdi) with $-1.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+       (__pthread_cond_signal): Xor FUTEX_WAKE_OP with FUTEX_WAKE instead
+       of oring.
+
+2007-08-13  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/i386/i786/Implies: New file.
+
+2007-08-13  Jakub Jelinek  <jakub@redhat.com>
+
+       * allocatestack.c: Include kernel-features.h.
+       * pthread_create.c: Likewise.
+       * pthread_mutex_init.c: Likewise.
+       * init.c: Likewise.
+       * pthread_cond_timedwait.c: Likewise.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_wrlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_rdlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_unlock.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_cond_timedwait.S: Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedwrlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/i386/i486/pthread_rwlock_timedrdlock.S:
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h: Likewise.
+       * sysdeps/unix/sysv/linux/sh/pthread_cond_timedwait.S: Likewise.
+
+2007-08-12  Jakub Jelinek  <jakub@redhat.com>
+
+       * sysdeps/unix/sysv/linux/sparc/bits/pthreadtypes.h
+       [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+       byte elements.  One of them is the new __shared element.
+       [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+       adjust names of other padding elements.
+       * sysdeps/unix/sysv/linux/s390/bits/pthreadtypes.h
+       [__WORDSIZE=32] (pthread_rwlock_t): Split __flags element into four
+       byte elements.  One of them is the new __shared element.
+       [__WORDSIZE=64] (pthread_rwlock_t): Renamed __pad1 element to __shared,
+       adjust names of other padding elements.
+       * sysdeps/unix/sysv/linux/ia64/bits/pthreadtypes.h (pthread_rwlock_t):
+       Renamed __pad1 element to __shared, adjust names of other padding
+       elements.
+       * sysdeps/unix/sysv/linux/alpha/bits/pthreadtypes.h
+       (pthread_rwlock_t): Likewise.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (__lll_lock): Fix a
+       typo.
+
+2007-08-09  Anton Blanchard  <anton@samba.org>
+
+       * sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c: New file.
+
+2007-08-12  Ulrich Drepper  <drepper@redhat.com>
+
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S: Include
+       <kernel-features.h>.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S: Likewise.
+
+2007-08-11  Ulrich Drepper  <drepper@redhat.com>
+
+       * pthreadP.h (PTHREAD_ROBUST_MUTEX_PSHARED): Define.
+       * pthread_mutex_lock.c: Use it instead of PTHREAD_MUTEX_PSHARED when
+       dealing with robust mutexes.
+       * pthread_mutex_timedlock.c: Likewise.
+       * pthread_mutex_trylock.c: Likewise.
+       * pthread_mutex_unlock.c: Likewise.
+       * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c: Likewise.
+
+2007-08-06  Jakub Jelinek  <jakub@redhat.com>
+
+       * pthreadP.h (PTHREAD_MUTEX_PSHARED_BIT): Define.
+       (PTHREAD_MUTEX_TYPE): Mask __kind with 127.
+       (PTHREAD_MUTEX_PSHARED): Define.
+       * pthread_mutex_init.c (__pthread_mutex_init): Set
+       PTHREAD_MUTEX_PSHARED_BIT for pshared or robust
+       mutexes.
+       * pthread_mutex_lock.c (LLL_MUTEX_LOCK): Take mutex as argument
+       instead of its __data.__lock field, pass PTHREAD_MUTEX_PSHARED
+       as second argument to lll_lock.
+       (LLL_MUTEX_TRYLOCK): Take mutex as argument
+       instead of its __data.__lock field.
+       (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+       __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+       to lll_robust_lock.
+       (__pthread_mutex_lock): Update LLL_MUTEX_LOCK, LLL_MUTEX_TRYLOCK,
+       LLL_ROBUST_MUTEX_LOCK users, use PTHREAD_MUTEX_TYPE (mutex)
+       instead of mutex->__data.__kind directly, pass
+       PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock and lll_futex_wait.
+       * pthread_mutex_trylock.c (__pthread_mutex_trylock): Use
+       PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+       directly, pass PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock.
+       (pthread_mutex_timedlock): Pass PTHREAD_MUTEX_PSHARED (mutex)
+       to lll_timedlock, lll_robust_timedlock, lll_unlock and
+       lll_futex_timed_wait.  Use PTHREAD_MUTEX_TYPE (mutex) instead
+       of mutex->__data.__kind directly.
+       * pthread_mutex_timedlock.c (pthread_mutex_timedlock): Pass
+       PTHREAD_MUTEX_PSHARED (mutex) to lll_timedlock,
+       lll_robust_timedlock, lll_unlock and lll_futex_timed_wait.  Use
+       PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind directly.
+       * pthread_mutex_unlock.c (__pthread_mutex_unlock_usercnt): Pass
+       PTHREAD_MUTEX_PSHARED (mutex) to lll_unlock, lll_robust_unlock
+       and lll_futex_wake.
+       * pthread_mutex_setprioceiling.c (pthread_mutex_setprioceiling): Pass
+       PTHREAD_MUTEX_PSHARED (mutex) to lll_futex_wait and lll_futex_wake.
+       Use PTHREAD_MUTEX_TYPE (mutex) instead of mutex->__data.__kind
+       directly.
+       * sysdeps/unix/sysv/linux/pthread_mutex_cond_lock.c (LLL_MUTEX_LOCK):
+       Take mutex as argument instead of its __data.__lock field, pass
+       PTHREAD_MUTEX_PSHARED as second argument to lll_cond_lock.
+       (LLL_MUTEX_TRYLOCK): Take mutex as argument instead of its
+       __data.__lock field.
+       (LLL_ROBUST_MUTEX_LOCK): Take mutex as argument instead of its
+       __data.__lock field, pass PTHREAD_MUTEX_PSHARED as second argument
+       to lll_robust_cond_lock.
+       * pthread_cond_broadcast.c (__pthread_cond_broadcast): Add pshared
+       variable, pass it to lll_lock, lll_unlock, lll_futex_requeue and
+       lll_futex_wake.  Don't use lll_futex_requeue if dependent mutex
+       has PTHREAD_MUTEX_PSHARED_BIT bit set in its __data.__kind.
+       * pthread_cond_destroy.c (__pthread_cond_destroy): Add pshared
+       variable, pass it to lll_lock, lll_unlock, lll_futex_wake and
+       lll_futex_wait.
+       * pthread_cond_signal.c (__pthread_cond_signal): Add pshared
+       variable, pass it to lll_lock, lll_unlock, lll_futex_wake_unlock and
+       lll_futex_wake.
+       * pthread_cond_timedwait.c (__pthread_cond_wait): Add
+       pshared variable, pass it to lll_lock, lll_unlock,
+       lll_futex_timedwait and lll_futex_wake.
+       * pthread_cond_wait.c (__condvar_cleanup, __pthread_cond_wait): Add
+       pshared variable, pass it to lll_lock, lll_unlock, lll_futex_wait
+       and lll_futex_wake.
+       * sysdeps/unix/sysv/linux/alpha/lowlevellock.h (lll_futex_requeue,
+       lll_futex_wake_unlock): Add private argument, use __lll_private_flag
+       macro.
+       * sysdeps/unix/sysv/linux/ia64/lowlevellock.h (lll_futex_requeue,
+       lll_futex_wake_unlock): Likewise.
+       * sysdeps/unix/sysv/linux/powerpc/lowlevellock.h (lll_futex_requeue):
+       Likewise.
+       * sysdeps/unix/sysv/linux/sparc/lowlevellock.h (lll_futex_requeue,
+       lll_futex_wake_unlock): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_futex_requeue):
+       Likewise.
+       * sysdeps/unix/sysv/linux/s390/lowlevellock.h (lll_futex_requeue,
+       lll_futex_wake_unlock): Likewise.
+       (lll_futex_wake): Fix a typo.
+       * sysdeps/unix/sysv/linux/pthread-pi-defines.sym (PS_BIT): Add.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_broadcast.S
+       (__pthread_cond_broadcast): Pass LLL_PRIVATE to lll_* and or
+       FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+       Don't use FUTEX_CMP_REQUEUE if dep_mutex is not process private.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_signal.S
+       (__pthread_cond_signal): Pass LLL_PRIVATE to lll_* and or
+       FUTEX_PRIVATE_FLAG into SYS_futex op if cv is process private.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_timedwait.S
+       (__pthread_cond_timedwait): Likewise.
+       * sysdeps/unix/sysv/linux/x86_64/pthread_cond_wait.S:
+       (__condvar_cleanup, __pthread_cond_wait): Likewise.
+
 2007-08-05  Jakub Jelinek  <jakub@redhat.com>
 
        * sysdeps/unix/sysv/linux/powerpc/powerpc32/sysdep-cancel.h (PSEUDO):
index f30c88f..02a84f4 100644 (file)
@@ -28,6 +28,7 @@
 #include <dl-sysdep.h>
 #include <tls.h>
 #include <lowlevellock.h>
+#include <kernel-features.h>
 
 
 #ifndef NEED_SEPARATE_REGISTER_STACK
index 95b9c7b..ffb50b4 100644 (file)
@@ -33,6 +33,7 @@
 #include <shlib-compat.h>
 #include <smp.h>
 #include <lowlevellock.h>
+#include <kernel-features.h>
 
 
 /* Size and alignment of static TLS block.  */
index 82c0f1e..17b6492 100644 (file)
@@ -96,9 +96,22 @@ enum
   PTHREAD_MUTEX_PP_ADAPTIVE_NP
   = PTHREAD_MUTEX_PRIO_PROTECT_NP | PTHREAD_MUTEX_ADAPTIVE_NP
 };
+#define PTHREAD_MUTEX_PSHARED_BIT 128
 
 #define PTHREAD_MUTEX_TYPE(m) \
-  ((m)->__data.__kind)
+  ((m)->__data.__kind & 127)
+
+#if LLL_PRIVATE == 0 && LLL_SHARED == 128
+# define PTHREAD_MUTEX_PSHARED(m) \
+  ((m)->__data.__kind & 128)
+#else
+# define PTHREAD_MUTEX_PSHARED(m) \
+  (((m)->__data.__kind & 128) ? LLL_SHARED : LLL_PRIVATE)
+#endif
+
+/* The kernel when waking robust mutexes on exit never uses
+   FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */
+#define PTHREAD_ROBUST_MUTEX_PSHARED(m) LLL_SHARED
 
 /* Ceiling in __data.__lock.  __data.__lock is signed, so don't
    use the MSB bit in there, but in the mask also include that bit,
index 5c0d76e..22523c2 100644 (file)
@@ -32,8 +32,10 @@ int
 __pthread_cond_broadcast (cond)
      pthread_cond_t *cond;
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
   /* Make sure we are alone.  */
-  lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Are there any waiters to be woken?  */
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -47,7 +49,7 @@ __pthread_cond_broadcast (cond)
       ++cond->__data.__broadcast_seq;
 
       /* We are done.  */
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
 
       /* Do not use requeue for pshared condvars.  */
       if (cond->__data.__mutex == (void *) ~0l)
@@ -57,21 +59,22 @@ __pthread_cond_broadcast (cond)
       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))
+      /* XXX: Kernel so far can only requeue to the same type of futex,
+        in this case private (we don't requeue for pshared condvars).  */
+      if (__builtin_expect (mut->__data.__kind
+                           & (PTHREAD_MUTEX_PRIO_INHERIT_NP
+                              | PTHREAD_MUTEX_PSHARED_BIT), 0))
        goto wake_all;
 
       /* lll_futex_requeue returns 0 for success and non-zero
         for errors.  */
       if (__builtin_expect (lll_futex_requeue (&cond->__data.__futex, 1,
                                               INT_MAX, &mut->__data.__lock,
-                                              futex_val), 0))
+                                              futex_val, LLL_PRIVATE), 0))
        {
          /* The requeue functionality is not available.  */
        wake_all:
-         lll_futex_wake (&cond->__data.__futex, INT_MAX,
-                         // XYZ check mutex flag
-                         LLL_SHARED);
+         lll_futex_wake (&cond->__data.__futex, INT_MAX, pshared);
        }
 
       /* That's all.  */
@@ -79,7 +82,7 @@ __pthread_cond_broadcast (cond)
     }
 
   /* We are done.  */
-  lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_unlock (cond->__data.__lock, pshared);
 
   return 0;
 }
index 53b5cd2..35135a6 100644 (file)
@@ -26,14 +26,17 @@ int
 __pthread_cond_destroy (cond)
      pthread_cond_t *cond;
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are alone.  */
-  lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cond->__data.__lock, pshared);
 
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
     {
       /* If there are still some waiters which have not been
         woken up, this is an application bug.  */
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
       return EBUSY;
     }
 
@@ -60,19 +63,16 @@ __pthread_cond_destroy (cond)
        {
          pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
          lll_futex_wake (&mut->__data.__lock, INT_MAX,
-                         // XYZ check mutex flag
-                         LLL_SHARED);
+                         PTHREAD_MUTEX_PSHARED (mut));
        }
 
       do
        {
-         lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+         lll_unlock (cond->__data.__lock, pshared);
 
-         lll_futex_wait (&cond->__data.__nwaiters, nwaiters,
-                         // XYZ check mutex flag
-                         LLL_SHARED);
+         lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
 
-         lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+         lll_lock (cond->__data.__lock, pshared);
 
          nwaiters = cond->__data.__nwaiters;
        }
index f2de58f..023bbb5 100644 (file)
@@ -32,8 +32,11 @@ int
 __pthread_cond_signal (cond)
      pthread_cond_t *cond;
 {
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are alone.  */
-  lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Are there any waiters to be woken?  */
   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
@@ -45,18 +48,14 @@ __pthread_cond_signal (cond)
       /* Wake one.  */
       if (! __builtin_expect (lll_futex_wake_unlock (&cond->__data.__futex, 1,
                                                     1, &cond->__data.__lock,
-                                                    // XYZ check mutex flag
-                                                    LLL_SHARED),
-                                                    0))
+                                                    pshared), 0))
        return 0;
 
-      lll_futex_wake (&cond->__data.__futex, 1,
-                     // XYZ check mutex flag
-                     LLL_SHARED);
+      lll_futex_wake (&cond->__data.__futex, 1, pshared);
     }
 
   /* We are done.  */
-  lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_unlock (cond->__data.__lock, pshared);
 
   return 0;
 }
index a8d95dc..9d268e9 100644 (file)
@@ -23,6 +23,7 @@
 #include <lowlevellock.h>
 #include <pthread.h>
 #include <pthreadP.h>
+#include <kernel-features.h>
 
 #include <shlib-compat.h>
 
@@ -53,14 +54,17 @@ __pthread_cond_timedwait (cond, mutex, abstime)
   if (abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
     return EINVAL;
 
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
+
   /* Make sure we are along.  */
-  lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Now we can release the mutex.  */
   int err = __pthread_mutex_unlock_usercnt (mutex, 0);
   if (err)
     {
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
       return err;
     }
 
@@ -146,22 +150,20 @@ __pthread_cond_timedwait (cond, mutex, abstime)
       unsigned int futex_val = cond->__data.__futex;
 
       /* Prepare to wait.  Release the condvar futex.  */
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
 
       /* Enable asynchronous cancellation.  Required by the standard.  */
       cbuffer.oldtype = __pthread_enable_asynccancel ();
 
       /* Wait until woken by signal or broadcast.  */
       err = lll_futex_timed_wait (&cond->__data.__futex,
-                                 futex_val, &rt,
-                                 // XYZ check mutex flag
-                                 LLL_SHARED);
+                                 futex_val, &rt, pshared);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (cbuffer.oldtype);
 
       /* We are going to look at shared data again, so get the lock.  */
-      lll_lock(cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_lock (cond->__data.__lock, pshared);
 
       /* If a broadcast happened, we are done.  */
       if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -198,12 +200,10 @@ __pthread_cond_timedwait (cond, mutex, abstime)
      and it can be successfully destroyed.  */
   if (cond->__data.__total_seq == -1ULL
       && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
-    lll_futex_wake (&cond->__data.__nwaiters, 1,
-                   // XYZ check mutex flag
-                   LLL_SHARED);
+    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
 
   /* We are done with the condvar.  */
-  lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_unlock (cond->__data.__lock, pshared);
 
   /* The cancellation handling is back to normal, remove the handler.  */
   __pthread_cleanup_pop (&buffer, 0);
index 679655f..670fba5 100644 (file)
@@ -43,9 +43,11 @@ __condvar_cleanup (void *arg)
   struct _condvar_cleanup_buffer *cbuffer =
     (struct _condvar_cleanup_buffer *) arg;
   unsigned int destroying;
+  int pshared = (cbuffer->cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
 
   /* We are going to modify shared data.  */
-  lll_lock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cbuffer->cond->__data.__lock, pshared);
 
   if (cbuffer->bc_seq == cbuffer->cond->__data.__broadcast_seq)
     {
@@ -71,20 +73,16 @@ __condvar_cleanup (void *arg)
   if (cbuffer->cond->__data.__total_seq == -1ULL
       && cbuffer->cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
     {
-      lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1,
-                     // XYZ check mutex flag
-                     LLL_SHARED);
+      lll_futex_wake (&cbuffer->cond->__data.__nwaiters, 1, pshared);
       destroying = 1;
     }
 
   /* We are done.  */
-  lll_unlock (cbuffer->cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_unlock (cbuffer->cond->__data.__lock, pshared);
 
   /* Wake everybody to make sure no condvar signal gets lost.  */
   if (! destroying)
-    lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX,
-                   // XYZ check mutex flag
-                   LLL_SHARED);
+    lll_futex_wake (&cbuffer->cond->__data.__futex, INT_MAX, pshared);
 
   /* Get the mutex before returning unless asynchronous cancellation
      is in effect.  */
@@ -100,15 +98,17 @@ __pthread_cond_wait (cond, mutex)
   struct _pthread_cleanup_buffer buffer;
   struct _condvar_cleanup_buffer cbuffer;
   int err;
+  int pshared = (cond->__data.__mutex == (void *) ~0l)
+               ? LLL_SHARED : LLL_PRIVATE;
 
   /* Make sure we are along.  */
-  lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_lock (cond->__data.__lock, pshared);
 
   /* Now we can release the mutex.  */
   err = __pthread_mutex_unlock_usercnt (mutex, 0);
   if (__builtin_expect (err, 0))
     {
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
       return err;
     }
 
@@ -144,21 +144,19 @@ __pthread_cond_wait (cond, mutex)
       unsigned int futex_val = cond->__data.__futex;
 
       /* Prepare to wait.  Release the condvar futex.  */
-      lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (cond->__data.__lock, pshared);
 
       /* Enable asynchronous cancellation.  Required by the standard.  */
       cbuffer.oldtype = __pthread_enable_asynccancel ();
 
       /* Wait until woken by signal or broadcast.  */
-      lll_futex_wait (&cond->__data.__futex, futex_val,
-                     // XYZ check mutex flag
-                     LLL_SHARED);
+      lll_futex_wait (&cond->__data.__futex, futex_val, pshared);
 
       /* Disable asynchronous cancellation.  */
       __pthread_disable_asynccancel (cbuffer.oldtype);
 
       /* We are going to look at shared data again, so get the lock.  */
-      lll_lock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_lock (cond->__data.__lock, pshared);
 
       /* If a broadcast happened, we are done.  */
       if (cbuffer.bc_seq != cond->__data.__broadcast_seq)
@@ -181,12 +179,10 @@ __pthread_cond_wait (cond, mutex)
      and it can be successfully destroyed.  */
   if (cond->__data.__total_seq == -1ULL
       && cond->__data.__nwaiters < (1 << COND_NWAITERS_SHIFT))
-    lll_futex_wake (&cond->__data.__nwaiters, 1,
-                   // XYZ check mutex flag
-                   LLL_SHARED);
+    lll_futex_wake (&cond->__data.__nwaiters, 1, pshared);
 
   /* We are done with the condvar.  */
-  lll_unlock (cond->__data.__lock, /* XYZ */ LLL_SHARED);
+  lll_unlock (cond->__data.__lock, pshared);
 
   /* The cancellation handling is back to normal, remove the handler.  */
   __pthread_cleanup_pop (&buffer, 0);
index 3ab2fa4..e08b76a 100644 (file)
@@ -27,6 +27,7 @@
 #include <atomic.h>
 #include <libc-internal.h>
 #include <resolv.h>
+#include <kernel-features.h>
 
 #include <shlib-compat.h>
 
index 96f1fb0..d9b1ef0 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+   Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -20,6 +21,7 @@
 #include <assert.h>
 #include <errno.h>
 #include <string.h>
+#include <kernel-features.h>
 #include "pthreadP.h"
 
 static const struct pthread_mutexattr default_attr =
@@ -120,6 +122,12 @@ __pthread_mutex_init (mutex, mutexattr)
       break;
     }
 
+  /* The kernel when waking robust mutexes on exit never uses
+     FUTEX_PRIVATE_FLAG FUTEX_WAKE.  */
+  if ((imutexattr->mutexkind & (PTHREAD_MUTEXATTR_FLAG_PSHARED
+                               | PTHREAD_MUTEXATTR_FLAG_ROBUST)) != 0)
+    mutex->__data.__kind |= PTHREAD_MUTEX_PSHARED_BIT;
+
   /* Default values: mutex not used yet.  */
   // mutex->__count = 0;       already done by memset
   // mutex->__owner = 0;       already done by memset
index a82922e..ed98dfc 100644 (file)
 
 
 #ifndef LLL_MUTEX_LOCK
-# define LLL_MUTEX_LOCK(mutex) lll_lock (mutex, /* XYZ */ LLL_SHARED)
-# define LLL_MUTEX_TRYLOCK(mutex) lll_trylock (mutex)
-# define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_lock (mutex, id, /* XYZ */ LLL_SHARED)
+# define LLL_MUTEX_LOCK(mutex) \
+  lll_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+# define LLL_MUTEX_TRYLOCK(mutex) \
+  lll_trylock ((mutex)->__data.__lock)
+# define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+  lll_robust_lock ((mutex)->__data.__lock, id, \
+                  PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
 #endif
 
 
@@ -62,7 +66,7 @@ __pthread_mutex_lock (mutex)
        }
 
       /* We have to get the mutex.  */
-      LLL_MUTEX_LOCK (mutex->__data.__lock);
+      LLL_MUTEX_LOCK (mutex);
 
       assert (mutex->__data.__owner == 0);
       mutex->__data.__count = 1;
@@ -79,7 +83,7 @@ __pthread_mutex_lock (mutex)
     case PTHREAD_MUTEX_TIMED_NP:
     simple:
       /* Normal mutex.  */
-      LLL_MUTEX_LOCK (mutex->__data.__lock);
+      LLL_MUTEX_LOCK (mutex);
       assert (mutex->__data.__owner == 0);
       break;
 
@@ -87,7 +91,7 @@ __pthread_mutex_lock (mutex)
       if (! __is_smp)
        goto simple;
 
-      if (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0)
+      if (LLL_MUTEX_TRYLOCK (mutex) != 0)
        {
          int cnt = 0;
          int max_cnt = MIN (MAX_ADAPTIVE_COUNT,
@@ -96,7 +100,7 @@ __pthread_mutex_lock (mutex)
            {
              if (cnt++ >= max_cnt)
                {
-                 LLL_MUTEX_LOCK (mutex->__data.__lock);
+                 LLL_MUTEX_LOCK (mutex);
                  break;
                }
 
@@ -104,7 +108,7 @@ __pthread_mutex_lock (mutex)
              BUSY_WAIT_NOP;
 #endif
            }
-         while (LLL_MUTEX_TRYLOCK (mutex->__data.__lock) != 0);
+         while (LLL_MUTEX_TRYLOCK (mutex) != 0);
 
          mutex->__data.__spins += (cnt - mutex->__data.__spins) / 8;
        }
@@ -166,16 +170,15 @@ __pthread_mutex_lock (mutex)
          /* Check whether we already hold the mutex.  */
          if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
            {
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+             int kind = PTHREAD_MUTEX_TYPE (mutex);
+             if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
                  return EDEADLK;
                }
 
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+             if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
@@ -191,14 +194,15 @@ __pthread_mutex_lock (mutex)
                }
            }
 
-         oldval = LLL_ROBUST_MUTEX_LOCK (mutex->__data.__lock, id);
+         oldval = LLL_ROBUST_MUTEX_LOCK (mutex, id);
 
          if (__builtin_expect (mutex->__data.__owner
                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
            {
              /* This mutex is now not recoverable.  */
              mutex->__data.__count = 0;
-             lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+             lll_unlock (mutex->__data.__lock,
+                         PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
              return ENOTRECOVERABLE;
            }
@@ -410,8 +414,7 @@ __pthread_mutex_lock (mutex)
 
                if (oldval != ceilval)
                  lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
-                                 // XYZ check mutex flag
-                                 LLL_SHARED);
+                                 PTHREAD_MUTEX_PSHARED (mutex));
              }
            while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
                                                        ceilval | 2, ceilval)
index 301fb63..836c9a3 100644 (file)
@@ -47,12 +47,13 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
 
   /* Check whether we already hold the mutex.  */
   bool locked = false;
+  int kind = PTHREAD_MUTEX_TYPE (mutex);
   if (mutex->__data.__owner == THREAD_GETMEM (THREAD_SELF, tid))
     {
-      if (mutex->__data.__kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP)
+      if (kind == PTHREAD_MUTEX_PP_ERRORCHECK_NP)
        return EDEADLK;
 
-      if (mutex->__data.__kind == PTHREAD_MUTEX_PP_RECURSIVE_NP)
+      if (kind == PTHREAD_MUTEX_PP_RECURSIVE_NP)
        locked = true;
     }
 
@@ -81,8 +82,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
 
            if (oldval != ceilval)
              lll_futex_wait (&mutex->__data.__lock, ceilval | 2,
-                             // XYZ check mutex flag
-                             LLL_SHARED);
+                             PTHREAD_MUTEX_PSHARED (mutex));
          }
        while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
                                                    ceilval | 2, ceilval)
@@ -113,8 +113,7 @@ pthread_mutex_setprioceiling (mutex, prioceiling, old_ceiling)
   atomic_full_barrier ();
 
   lll_futex_wake (&mutex->__data.__lock, INT_MAX,
-                 // XYZ check mutex flag
-                 LLL_SHARED);
+                 PTHREAD_MUTEX_PSHARED (mutex));
 
   return 0;
 }
index 7a0ed57..4bf0efe 100644 (file)
@@ -57,7 +57,7 @@ pthread_mutex_timedlock (mutex, abstime)
 
       /* We have to get the mutex.  */
       result = lll_timedlock (mutex->__data.__lock, abstime,
-                             /* XYZ */ LLL_SHARED);
+                             PTHREAD_MUTEX_PSHARED (mutex));
 
       if (result != 0)
        goto out;
@@ -78,7 +78,7 @@ pthread_mutex_timedlock (mutex, abstime)
     simple:
       /* Normal mutex.  */
       result = lll_timedlock (mutex->__data.__lock, abstime,
-                             /* XYZ */ LLL_SHARED);
+                             PTHREAD_MUTEX_PSHARED (mutex));
       break;
 
     case PTHREAD_MUTEX_ADAPTIVE_NP:
@@ -95,7 +95,7 @@ pthread_mutex_timedlock (mutex, abstime)
              if (cnt++ >= max_cnt)
                {
                  result = lll_timedlock (mutex->__data.__lock, abstime,
-                                         /* XYZ */ LLL_SHARED);
+                                         PTHREAD_MUTEX_PSHARED (mutex));
                  break;
                }
 
@@ -152,16 +152,15 @@ pthread_mutex_timedlock (mutex, abstime)
          /* Check whether we already hold the mutex.  */
          if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
            {
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+             int kind = PTHREAD_MUTEX_TYPE (mutex);
+             if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
                  return EDEADLK;
                }
 
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+             if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
@@ -178,14 +177,15 @@ pthread_mutex_timedlock (mutex, abstime)
            }
 
          result = lll_robust_timedlock (mutex->__data.__lock, abstime, id,
-                                        /* XYZ */ LLL_SHARED);
+                                        PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
 
          if (__builtin_expect (mutex->__data.__owner
                                == PTHREAD_MUTEX_NOTRECOVERABLE, 0))
            {
              /* This mutex is now not recoverable.  */
              mutex->__data.__count = 0;
-             lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+             lll_unlock (mutex->__data.__lock,
+                         PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
              return ENOTRECOVERABLE;
            }
@@ -446,8 +446,7 @@ pthread_mutex_timedlock (mutex, abstime)
 
                    lll_futex_timed_wait (&mutex->__data.__lock,
                                          ceilval | 2, &rt,
-                                         // XYZ check mutex flag
-                                         LLL_SHARED);
+                                         PTHREAD_MUTEX_PSHARED (mutex));
                  }
              }
            while (atomic_compare_and_exchange_val_acq (&mutex->__data.__lock,
index 9478d38..f6e24d4 100644 (file)
@@ -115,16 +115,15 @@ __pthread_mutex_trylock (mutex)
          /* Check whether we already hold the mutex.  */
          if (__builtin_expect ((oldval & FUTEX_TID_MASK) == id, 0))
            {
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
+             int kind = PTHREAD_MUTEX_TYPE (mutex);
+             if (kind == PTHREAD_MUTEX_ROBUST_ERRORCHECK_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
                  return EDEADLK;
                }
 
-             if (mutex->__data.__kind
-                 == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
+             if (kind == PTHREAD_MUTEX_ROBUST_RECURSIVE_NP)
                {
                  THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending,
                                 NULL);
@@ -154,7 +153,8 @@ __pthread_mutex_trylock (mutex)
              /* This mutex is now not recoverable.  */
              mutex->__data.__count = 0;
              if (oldval == id)
-               lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+               lll_unlock (mutex->__data.__lock,
+                           PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
              THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
              return ENOTRECOVERABLE;
            }
index 6226089..d33d059 100644 (file)
@@ -61,7 +61,7 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
        --mutex->__data.__nusers;
 
       /* Unlock.  */
-      lll_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_unlock (mutex->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex));
       break;
 
     case PTHREAD_MUTEX_ROBUST_RECURSIVE_NP:
@@ -115,7 +115,8 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
        --mutex->__data.__nusers;
 
       /* Unlock.  */
-      lll_robust_unlock (mutex->__data.__lock, /* XYZ */ LLL_SHARED);
+      lll_robust_unlock (mutex->__data.__lock,
+                        PTHREAD_ROBUST_MUTEX_PSHARED (mutex));
 
       THREAD_SETMEM (THREAD_SELF, robust_head.list_op_pending, NULL);
       break;
@@ -242,8 +243,7 @@ __pthread_mutex_unlock_usercnt (mutex, decr)
 
       if ((oldval & ~PTHREAD_MUTEX_PRIO_CEILING_MASK) > 1)
        lll_futex_wake (&mutex->__data.__lock, 1,
-                       // XYZ check mutex flag
-                       LLL_SHARED);
+                       PTHREAD_MUTEX_PSHARED (mutex));
 
       int oldprio = newval >> PTHREAD_MUTEX_PRIO_CEILING_SHIFT;
       return __pthread_tpp_change_priority (oldprio, -1);
index 41a54d4..41c0be1 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-specific pthread type layouts.  Alpha version.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 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
@@ -126,9 +126,9 @@ typedef union
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
     int __writer;
-    int __pad1;
+    int __shared;
+    unsigned long int __pad1;
     unsigned long int __pad2;
-    unsigned long int __pad3;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned int __flags;
index f3f2919..4f67964 100644 (file)
@@ -24,6 +24,7 @@
 #include <bits/pthreadtypes.h>
 #include <atomic.h>
 #include <sysdep.h>
+#include <kernel-features.h>
 
 
 #define __NR_futex             394
   while (0)
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_CMP_REQUEUE, (nr_wake),         \
-                             (nr_move), (mutex), (val));                     \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+                             (nr_wake), (nr_move), (mutex), (val));          \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
 
 /* 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;                                                          \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_WAKE_OP, (nr_wake),             \
-                             (nr_wake2), (futexp2),                          \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_WAKE_OP, private),    \
+                             (nr_wake), (nr_wake2), (futexp2),               \
                              FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                 \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
index 122d83a..776c47f 100644 (file)
@@ -83,11 +83,18 @@ __pthread_cond_broadcast:
        je      9f
 
        /* XXX: The kernel so far doesn't support requeue to PI futex.  */
-       testl   $PI_BIT, MUTEX_KIND(%edi)
+       /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+          type of futex (private resp. shared).  */
+       testl   $(PI_BIT | PS_BIT), MUTEX_KIND(%edi)
        jne     9f
 
        /* Wake up all threads.  */
-       movl    $FUTEX_CMP_REQUEUE, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %ecx
+#else
+       movl    %gs:PRIVATE_FUTEX, %ecx
+       orl     $FUTEX_CMP_REQUEUE, %ecx
+#endif
        movl    $SYS_futex, %eax
        movl    $0x7fffffff, %esi
        movl    $1, %edx
@@ -132,28 +139,63 @@ __pthread_cond_broadcast:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     2b
 
        /* Unlock in loop requires waekup.  */
 5:     leal    cond_lock-cond_futex(%ebx), %eax
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     6b
 
        /* Unlock in loop requires waekup.  */
 7:     leal    cond_lock-cond_futex(%ebx), %eax
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     8b
 
 9:     /* The futex requeue functionality is not available.  */
        movl    $0x7fffffff, %edx
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $SYS_futex, %eax
        ENTER_KERNEL
        jmp     10b
index e3510c8..36a1803 100644 (file)
@@ -70,7 +70,18 @@ __pthread_cond_signal:
        /* Wake up one thread.  */
        pushl   %esi
        pushl   %ebp
-       movl    $FUTEX_WAKE_OP, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE_OP, %ecx
        movl    $SYS_futex, %eax
        movl    $1, %edx
        movl    $1, %esi
@@ -92,7 +103,9 @@ __pthread_cond_signal:
        popl    %ebx
        ret
 
-7:     movl    $FUTEX_WAKE, %ecx
+7:     /* %ecx should be either FUTEX_WAKE_OP or
+          FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall.  */
+       xorl    $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %ecx
        movl    $SYS_futex, %eax
        /* %edx should be 1 already from $FUTEX_WAKE_OP syscall.
        movl    $1, %edx  */
@@ -106,8 +119,16 @@ __pthread_cond_signal:
 
        /* Unlock in loop requires wakeup.  */
 5:     movl    %edi, %eax
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     6b
 
@@ -118,8 +139,16 @@ __pthread_cond_signal:
 #else
        leal    cond_lock(%edi), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%edi)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     2b
 
index 79a7497..83f8db2 100644 (file)
@@ -22,6 +22,7 @@
 #include <lowlevellock.h>
 #include <lowlevelcond.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
        .text
@@ -157,7 +158,20 @@ __pthread_cond_timedwait:
        movl    %eax, (%esp)
 
        leal    4(%esp), %esi
-       xorl    %ecx, %ecx      /* movl $FUTEX_WAIT, %ecx */
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+       addl    $FUTEX_WAIT, %ecx
+#endif
        movl    %edi, %edx
        addl    $cond_futex, %ebx
 .Ladd_cond_futex:
@@ -231,7 +245,18 @@ __pthread_cond_timedwait:
 
        addl    $cond_nwaiters, %ebx
        movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $1, %edx
        ENTER_KERNEL
        subl    $cond_nwaiters, %ebx
@@ -279,8 +304,16 @@ __pthread_cond_timedwait:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     2b
 
@@ -292,8 +325,16 @@ __pthread_cond_timedwait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     4b
 
@@ -304,8 +345,16 @@ __pthread_cond_timedwait:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     6b
 
@@ -316,8 +365,16 @@ __pthread_cond_timedwait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     11b
 
@@ -338,8 +395,16 @@ __pthread_cond_timedwait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
 
        movl    %esi, %eax
@@ -400,8 +465,16 @@ __condvar_tw_cleanup:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
 
 1:     movl    broadcast_seq(%ebx), %eax
@@ -440,7 +513,18 @@ __condvar_tw_cleanup:
 
        addl    $cond_nwaiters, %ebx
        movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $1, %edx
        ENTER_KERNEL
        subl    $cond_nwaiters, %ebx
@@ -459,15 +543,34 @@ __condvar_tw_cleanup:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
 
        /* Wake up all waiters to make sure no signal gets lost.  */
 2:     testl   %edi, %edi
        jnz     5f
        addl    $cond_futex, %ebx
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $SYS_futex, %eax
        movl    $0x7fffffff, %edx
        ENTER_KERNEL
@@ -587,12 +690,12 @@ __condvar_tw_cleanup:
        .uleb128 20
        .byte   0x83                            # DW_CFA_offset %ebx
        .uleb128 5
-       .byte   2                               # DW_CFA_advance_loc1
-       .byte   .Lsubl-.Lpush_ebx
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .Lsubl-.Lpush_ebx
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20+FRAME_SIZE
-       .byte   3                               # DW_CFA_advance_loc2
-       .2byte  .Laddl-.Lsubl
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .Laddl-.Lsubl
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20
        .byte   0x40+.Lpop_ebx-.Laddl           # DW_CFA_advance_loc+N
@@ -614,7 +717,8 @@ __condvar_tw_cleanup:
        .byte   0x40+.LSbl1-.Lpop_edi           # DW_CFA_advance_loc+N
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20
-       .byte   0x40+.LSbl2-.LSbl1              # DW_CFA_advance_loc+N
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .LSbl2-.LSbl1
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20+FRAME_SIZE
        .byte   0x85                            # DW_CFA_offset %ebp
@@ -625,14 +729,15 @@ __condvar_tw_cleanup:
        .uleb128 4
        .byte   0x83                            # DW_CFA_offset %ebx
        .uleb128 5
-       .byte   0x40+.LSbl3-.LSbl2              # DW_CFA_advance_loc+N
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .LSbl3-.LSbl2
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20
+       .byte   4                               # DW_CFA_advance_loc4
 #if defined __NR_clock_gettime && !defined __ASSUME_POSIX_TIMERS
-       .byte   0x40+.LSbl4-.LSbl3              # DW_CFA_advance_loc+N
+       .4byte  .LSbl4-.LSbl3
 #else
-       .byte   4                               # DW_CFA_advance_loc4
-       .long   .LSbl5-.LSbl3
+       .4byte  .LSbl5-.LSbl3
 #endif
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 20+FRAME_SIZE
index 68741bf..5b30197 100644 (file)
@@ -22,6 +22,7 @@
 #include <lowlevellock.h>
 #include <lowlevelcond.h>
 #include <tcb-offsets.h>
+#include <kernel-features.h>
 
 
        .text
@@ -100,7 +101,20 @@ __pthread_cond_wait:
 4:     call    __pthread_enable_asynccancel
        movl    %eax, (%esp)
 
-       movl    %esi, %ecx      /* movl $FUTEX_WAIT, %ecx */
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+#if FUTEX_WAIT != 0
+       addl    $FUTEX_WAIT, %ecx
+#endif
        movl    %edi, %edx
        addl    $cond_futex, %ebx
 .Ladd_cond_futex:
@@ -161,7 +175,18 @@ __pthread_cond_wait:
 
        addl    $cond_nwaiters, %ebx
        movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $1, %edx
        ENTER_KERNEL
        subl    $cond_nwaiters, %ebx
@@ -197,8 +222,16 @@ __pthread_cond_wait:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     2b
 
@@ -210,8 +243,16 @@ __pthread_cond_wait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     4b
 
@@ -222,8 +263,16 @@ __pthread_cond_wait:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
        jmp     6b
 
@@ -234,8 +283,16 @@ __pthread_cond_wait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
        jmp     11b
 
@@ -256,8 +313,16 @@ __pthread_cond_wait:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
 
        movl    %esi, %eax
@@ -292,8 +357,16 @@ __condvar_w_cleanup:
 #else
        leal    cond_lock(%ebx), %edx
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_lock_wait
 
 1:     movl    broadcast_seq(%ebx), %eax
@@ -332,7 +405,18 @@ __condvar_w_cleanup:
 
        addl    $cond_nwaiters, %ebx
        movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_nwaiters(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $1, %edx
        ENTER_KERNEL
        subl    $cond_nwaiters, %ebx
@@ -351,15 +435,34 @@ __condvar_w_cleanup:
 #else
        leal    cond_lock(%ebx), %eax
 #endif
-       /* XYZ */
-       movl    $LLL_SHARED, %ecx
+#if (LLL_SHARED-LLL_PRIVATE) > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex(%ebx)
+       setne   %cl
+       subl    $1, %ecx
+       andl    $(LLL_SHARED-LLL_PRIVATE), %ecx
+#if LLL_PRIVATE != 0
+       addl    $LLL_PRIVATE, %ecx
+#endif
        call    __lll_unlock_wake
 
        /* Wake up all waiters to make sure no signal gets lost.  */
 2:     testl   %edi, %edi
        jnz     5f
        addl    $cond_futex, %ebx
-       movl    $FUTEX_WAKE, %ecx
+#if FUTEX_PRIVATE_FLAG > 255
+       xorl    %ecx, %ecx
+#endif
+       cmpl    $-1, dep_mutex-cond_futex(%ebx)
+       sete    %cl
+       subl    $1, %ecx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       andl    $FUTEX_PRIVATE_FLAG, %ecx
+#else
+       andl    %gs:PRIVATE_FUTEX, %ecx
+#endif
+       addl    $FUTEX_WAKE, %ecx
        movl    $SYS_futex, %eax
        movl    $0x7fffffff, %edx
        ENTER_KERNEL
@@ -473,12 +576,12 @@ __condvar_w_cleanup:
        .uleb128 16
        .byte   0x83                            # DW_CFA_offset %ebx
        .uleb128 4
-       .byte   2                               # DW_CFA_advance_loc1
-       .byte   .Lsubl-.Lpush_ebx
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .Lsubl-.Lpush_ebx
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 16+FRAME_SIZE
-       .byte   2                               # DW_CFA_advance_loc1
-       .byte   .Laddl-.Lsubl
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .Laddl-.Lsubl
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 16
        .byte   0x40+ .Lpop_ebx-.Laddl          # DW_CFA_advance_loc+N
@@ -502,13 +605,16 @@ __condvar_w_cleanup:
        .uleb128 3
        .byte   0x83                            # DW_CFA_offset %ebx
        .uleb128 4
-       .byte   0x40+.LSbl2-.LSbl1              # DW_CFA_advance_loc+N
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .LSbl2-.LSbl1
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 16+FRAME_SIZE
-       .byte   0x40+.LSbl3-.LSbl2              # DW_CFA_advance_loc+N
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .LSbl3-.LSbl2
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 16
-       .byte   0x40+.LSbl4-.LSbl3              # DW_CFA_advance_loc+N
+       .byte   4                               # DW_CFA_advance_loc4
+       .4byte  .LSbl4-.LSbl3
        .byte   14                              # DW_CFA_def_cfa_offset
        .uleb128 16+FRAME_SIZE
        .align  4
index d8a62ed..d8f1bd5 100644 (file)
@@ -21,6 +21,7 @@
 #include <lowlevellock.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
        .text
@@ -68,7 +69,7 @@ __pthread_rwlock_rdlock:
        jne     10f
 
 11:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
        movzbl  PSHARED(%ebx), %ecx
        xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
 #else
index 71b97c6..0d96e03 100644 (file)
@@ -21,6 +21,7 @@
 #include <lowlevellock.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
        .text
@@ -99,7 +100,7 @@ pthread_rwlock_timedrdlock:
        movl    %edx, 4(%esp)
 
        movl    %esi, %edx
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
        movzbl  PSHARED(%ebp), %ecx
        xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
 #else
index c002472..e78fdf6 100644 (file)
@@ -21,6 +21,7 @@
 #include <lowlevellock.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
        .text
@@ -97,7 +98,7 @@ pthread_rwlock_timedwrlock:
        movl    %edx, 4(%esp)
 
        movl    %esi, %edx
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
        movzbl  PSHARED(%ebp), %ecx
        xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
 #else
index fdad432..a23e1b5 100644 (file)
@@ -20,6 +20,7 @@
 #include <sysdep.h>
 #include <lowlevellock.h>
 #include <lowlevelrwlock.h>
+#include <kernel-features.h>
 
 
        .text
@@ -73,7 +74,7 @@ __pthread_rwlock_unlock:
        jne     7f
 
 8:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
        movzbl  PSHARED(%edi), %ecx
        xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAKE, %ecx
 #else
index 3f55c82..65b99fe 100644 (file)
@@ -21,6 +21,7 @@
 #include <lowlevellock.h>
 #include <lowlevelrwlock.h>
 #include <pthread-errnos.h>
+#include <kernel-features.h>
 
 
        .text
@@ -66,7 +67,7 @@ __pthread_rwlock_wrlock:
        jne     10f
 
 11:
-#if __ASSUME_PRIVATE_FUTEX
+#ifdef __ASSUME_PRIVATE_FUTEX
        movzbl  PSHARED(%ebx), %ecx
        xorl    $FUTEX_PRIVATE_FLAG|FUTEX_WAIT, %ecx
 #else
diff --git a/nptl/sysdeps/unix/sysv/linux/i386/i786/Implies b/nptl/sysdeps/unix/sysv/linux/i386/i786/Implies
new file mode 100644 (file)
index 0000000..7cb7d9a
--- /dev/null
@@ -0,0 +1,2 @@
+# The PPro and PII cores are mostly the same.
+unix/sysv/linux/i386/i686
index 2f663aa..8f67616 100644 (file)
@@ -83,7 +83,7 @@
       ? ((fl) | THREAD_GETMEM (THREAD_SELF, header.private_futex))           \
       : (fl))                                                                \
    : ({ unsigned int __fl = ((private) ^ FUTEX_PRIVATE_FLAG);                \
-       asm ("andl %%fs:%P1, %0" : "+r" (__fl)                                \
+       asm ("andl %%gs:%P1, %0" : "+r" (__fl)                                \
             : "i" (offsetof (struct pthread, header.private_futex)));        \
        __fl | (fl); }))
 # endif              
index 892769d..330717f 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -126,9 +126,9 @@ typedef union
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
     int __writer;
-    int __pad1;
+    int __shared;
+    unsigned long int __pad1;
     unsigned long int __pad2;
-    unsigned long int __pad3;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned int __flags;
index 3c28a39..ada7985 100644 (file)
@@ -25,6 +25,7 @@
 #include <bits/pthreadtypes.h>
 #include <ia64intrin.h>
 #include <atomic.h>
+#include <kernel-features.h>
 
 #define __NR_futex             1230
 #define FUTEX_WAIT             0
@@ -103,18 +104,20 @@ do                                                                        \
 while (0)
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val)                \
+#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private)       \
 ({                                                                          \
-   DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_CMP_REQUEUE,                     \
+   DO_INLINE_SYSCALL(futex, 6, (long) (ftx),                                \
+                    __lll_private_flag (FUTEX_CMP_REQUEUE, private),        \
                     (int) (nr_wake), (int) (nr_move), (long) (mutex),       \
                     (int) val);                                             \
    _r10 == -1;                                                              \
 })
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2)                 \
+#define lll_futex_wake_unlock(ftx, nr_wake, nr_wake2, ftx2, private)        \
 ({                                                                          \
-   DO_INLINE_SYSCALL(futex, 6, (long) (ftx), FUTEX_WAKE_OP,                 \
+   DO_INLINE_SYSCALL(futex, 6, (long) (ftx),                                \
+                    __lll_private_flag (FUTEX_WAKE_OP, private),            \
                     (int) (nr_wake), (int) (nr_wake2), (long) (ftx2),       \
                     FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                         \
    _r10 == -1;                                                              \
@@ -152,6 +155,7 @@ extern int __lll_robust_lock_wait (int *futex, int private) attribute_hidden;
          __lll_lock_wait_private (__futex);                                  \
        else                                                                  \
          __lll_lock_wait (__futex, private);                                 \
+      }                                                                              \
   }))
 #define lll_lock(futex, private) __lll_lock (&(futex), private)
 
index 41804d1..80b9a43 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
 #include <atomic.h>
+#include <kernel-features.h>
 
 #ifndef __NR_futex
 # define __NR_futex            221
   while (0)
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
                                                                              \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_CMP_REQUEUE, (nr_wake),         \
-                             (nr_move), (mutex), (val));                     \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+                             (nr_wake), (nr_move), (mutex), (val));          \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
 
diff --git a/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c b/nptl/sysdeps/unix/sysv/linux/powerpc/pthread_spin_unlock.c
new file mode 100644 (file)
index 0000000..90f2dc6
--- /dev/null
@@ -0,0 +1,29 @@
+/* pthread_spin_unlock -- unlock a spin lock.  PowerPC version.
+   Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "pthreadP.h"
+#include <lowlevellock.h>
+
+int
+pthread_spin_unlock (pthread_spinlock_t *lock)
+{
+  __asm __volatile (__lll_rel_instr ::: "memory");
+  *lock = 0;
+  return 0;
+}
index a1b6794..d985c6a 100644 (file)
@@ -4,3 +4,4 @@
 
 MUTEX_KIND     offsetof (pthread_mutex_t, __data.__kind)
 PI_BIT         PTHREAD_MUTEX_PRIO_INHERIT_NP
+PS_BIT         PTHREAD_MUTEX_PSHARED_BIT
index 81ecd65..93841c5 100644 (file)
@@ -1,8 +1,12 @@
 #include <pthreadP.h>
 
-#define LLL_MUTEX_LOCK(mutex) lll_cond_lock (mutex, /* XYZ */ LLL_SHARED)
-#define LLL_MUTEX_TRYLOCK(mutex) lll_cond_trylock (mutex)
-#define LLL_ROBUST_MUTEX_LOCK(mutex, id) lll_robust_cond_lock (mutex, id, /* XYZ */ LLL_SHARED)
+#define LLL_MUTEX_LOCK(mutex) \
+  lll_cond_lock ((mutex)->__data.__lock, PTHREAD_MUTEX_PSHARED (mutex))
+#define LLL_MUTEX_TRYLOCK(mutex) \
+  lll_cond_trylock ((mutex)->__data.__lock)
+#define LLL_ROBUST_MUTEX_LOCK(mutex, id) \
+  lll_robust_cond_lock ((mutex)->__data.__lock, id, \
+                       PTHREAD_ROBUST_MUTEX_PSHARED (mutex))
 #define __pthread_mutex_lock __pthread_mutex_cond_lock
 #define NO_INCR
 
index c77031d..c7345cd 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003.
 
@@ -159,9 +159,9 @@ typedef union
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
     int __writer;
-    int __pad1;
+    int __shared;
+    unsigned long int __pad1;
     unsigned long int __pad2;
-    unsigned long int __pad3;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned int __flags;
@@ -175,9 +175,12 @@ typedef union
     unsigned int __writer_wakeup;
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
+    unsigned char __pad1;
+    unsigned char __pad2;
+    unsigned char __shared;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
-    unsigned int __flags;
+    unsigned char __flags;
     int __writer;
   } __data;
 # endif
index ad4d273..7fee435 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
 #include <atomic.h>
+#include <kernel-features.h>
 
 #define SYS_futex              238
 #define FUTEX_WAIT             0
@@ -93,7 +94,7 @@
   ({                                                                         \
     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
     register unsigned long int __r3 asm ("3")                                \
-      __lll_private_flag (FUTEX_WAKE, private);                                      \
+      = __lll_private_flag (FUTEX_WAKE, private);                            \
     register unsigned long int __r4 asm ("4") = (unsigned long int) (nr);     \
     register unsigned long int __result asm ("2");                           \
                                                                              \
 
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futex, nr_wake, nr_move, mutex, val, private) \
   ({                                                                         \
     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
-    register unsigned long int __r3 asm ("3") = FUTEX_CMP_REQUEUE;           \
+    register unsigned long int __r3 asm ("3")                                \
+      = __lll_private_flag (FUTEX_CMP_REQUEUE, private);                     \
     register unsigned long int __r4 asm ("4") = (long int) (nr_wake);        \
     register unsigned long int __r5 asm ("5") = (long int) (nr_move);        \
     register unsigned long int __r6 asm ("6") = (unsigned long int) (mutex);  \
 
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2) \
+#define lll_futex_wake_unlock(futex, nr_wake, nr_wake2, futex2, private) \
   ({                                                                         \
     register unsigned long int __r2 asm ("2") = (unsigned long int) (futex);  \
-    register unsigned long int __r3 asm ("3") = FUTEX_WAKE_OP;       \
+    register unsigned long int __r3 asm ("3")                                \
+      = __lll_private_flag (FUTEX_WAKE_OP, private);                         \
     register unsigned long int __r4 asm ("4") = (long int) (nr_wake);        \
     register unsigned long int __r5 asm ("5") = (long int) (nr_wake2);       \
     register unsigned long int __r6 asm ("6") = (unsigned long int) (futex2); \
index 17c1e6f..fde4f57 100644 (file)
@@ -22,6 +22,7 @@
 #include <lowlevelcond.h>
 #include <pthread-errnos.h>
 #include "lowlevel-atomic.h"
+#include <kernel-features.h>
 
        .text
 
index e734c12..faf0584 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine-specific pthread type layouts.  SPARC version.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
 
@@ -160,9 +160,9 @@ typedef union
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
     int __writer;
-    int __pad1;
+    int __shared;
+    unsigned long int __pad1;
     unsigned long int __pad2;
-    unsigned long int __pad3;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
     unsigned int __flags;
@@ -176,9 +176,12 @@ typedef union
     unsigned int __writer_wakeup;
     unsigned int __nr_readers_queued;
     unsigned int __nr_writers_queued;
+    unsigned char __pad1;
+    unsigned char __pad2;
+    unsigned char __shared;
     /* FLAGS must stay at this position in the structure to maintain
        binary compatibility.  */
-    unsigned int __flags;
+    unsigned char __flags;
     int __writer;
   } __data;
 # endif
index 38692bb..f4512b2 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/param.h>
 #include <bits/pthreadtypes.h>
 #include <atomic.h>
+#include <kernel-features.h>
 
 
 #define FUTEX_WAIT             0
   })
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(futexp, nr_wake, nr_move, mutex, val, private) \
   ({                                                                         \
     INTERNAL_SYSCALL_DECL (__err);                                           \
     long int __ret;                                                          \
                                                                              \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_CMP_REQUEUE, (nr_wake),         \
-                             (nr_move), (mutex), (val));                     \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_CMP_REQUEUE, private),\
+                             (nr_wake), (nr_move), (mutex), (val));          \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
 
 /* Avoid FUTEX_WAKE_OP if supporting pre-v9 CPUs.  */
 # define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2) 1
 #else
-# 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;                                                          \
                                                                              \
-    __ret = INTERNAL_SYSCALL (futex, __err, 6,                               \
-                             (futexp), FUTEX_WAKE_OP, (nr_wake),             \
-                             (nr_wake2), (futexp2),                          \
+    __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp),                     \
+                             __lll_private_flag (FUTEX_WAKE_OP, private),    \
+                             (nr_wake), (nr_wake2), (futexp2),               \
                              FUTEX_OP_CLEAR_WAKE_IF_GT_ONE);                 \
     INTERNAL_SYSCALL_ERROR_P (__ret, __err);                                 \
   })
index 192d203..2cd69a1 100644 (file)
@@ -533,7 +533,7 @@ LLL_STUB_UNWIND_INFO_END
   while (0)
 
 /* Returns non-zero if error happened, zero if success.  */
-#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val) \
+#define lll_futex_requeue(ftx, nr_wake, nr_move, mutex, val, private) \
   ({ int __res;                                                                      \
      register int __nr_move __asm ("r10") = nr_move;                         \
      register void *__mutex __asm ("r8") = mutex;                            \
@@ -541,7 +541,8 @@ LLL_STUB_UNWIND_INFO_END
      __asm __volatile ("syscall"                                             \
                       : "=a" (__res)                                         \
                       : "0" (__NR_futex), "D" ((void *) ftx),                \
-                        "S" (FUTEX_CMP_REQUEUE), "d" (nr_wake),              \
+                        "S" (__lll_private_flag (FUTEX_CMP_REQUEUE,          \
+                                                 private)), "d" (nr_wake),   \
                         "r" (__nr_move), "r" (__mutex), "r" (__val)          \
                       : "cx", "r11", "cc", "memory");                        \
      __res < 0; })
index 0c619bf..6155255 100644 (file)
@@ -71,11 +71,18 @@ __pthread_cond_broadcast:
        je      9f
 
        /* XXX: The kernel so far doesn't support requeue to PI futex.  */
-       testl   $PI_BIT, MUTEX_KIND(%r8)
+       /* XXX: The kernel only supports FUTEX_CMP_REQUEUE to the same
+          type of futex (private resp. shared).  */
+       testl   $(PI_BIT | PS_BIT), MUTEX_KIND(%r8)
        jne     9f
 
        /* Wake up all threads.  */
-       movl    $FUTEX_CMP_REQUEUE, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $(FUTEX_CMP_REQUEUE|FUTEX_PRIVATE_FLAG), %esi
+#else
+       movl    %fs:PRIVATE_FUTEX, %esi
+       orl     $FUTEX_CMP_REQUEUE, %esi
+#endif
        movl    $SYS_futex, %eax
        movl    $1, %edx
        movl    $0x7fffffff, %r10d
@@ -104,8 +111,10 @@ __pthread_cond_broadcast:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
 #if cond_lock != 0
        subq    $cond_lock, %rdi
@@ -114,22 +123,36 @@ __pthread_cond_broadcast:
 
        /* Unlock in loop requires wakeup.  */
 5:     addq    $cond_lock-cond_futex, %rdi
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     6b
 
        /* Unlock in loop requires wakeup.  */
 7:     addq    $cond_lock-cond_futex, %rdi
-       /* XYZ */
+       cmpq    $-1, %r8
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        subq    $cond_lock-cond_futex, %rdi
        jmp     8b
 
 9:     /* The futex requeue functionality is not available.  */
+       cmpq    $-1, %r8
        movl    $0x7fffffff, %edx
-       movl    $FUTEX_WAKE, %esi
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE, %eax
+       movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE, %esi
+#endif
        movl    $SYS_futex, %eax
        syscall
        jmp     10b
index 2fc9d1f..8f65f2c 100644 (file)
@@ -55,10 +55,20 @@ __pthread_cond_signal:
        addl    $1, (%rdi)
 
        /* Wake up one thread.  */
-       movl    $FUTEX_WAKE_OP, %esi
-       movl    $SYS_futex, %eax
+       cmpq    $-1, dep_mutex(%r8)
        movl    $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE_OP, %eax
+       movl    $(FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE_OP, %esi
+#endif
        movl    $1, %r10d
+       movl    $SYS_futex, %eax
 #if cond_lock != 0
        addq    $cond_lock, %r8
 #endif
@@ -75,7 +85,9 @@ __pthread_cond_signal:
        xorl    %eax, %eax
        retq
 
-7:     movl    $FUTEX_WAKE, %esi
+7:     /* %esi should be either FUTEX_WAKE_OP or
+          FUTEX_WAKE_OP|FUTEX_PRIVATE_FLAG from the previous syscall.  */
+       xorl    $(FUTEX_WAKE ^ FUTEX_WAKE_OP), %esi
        movl    $SYS_futex, %eax
        /* %rdx should be 1 already from $FUTEX_WAKE_OP syscall.
        movl    $1, %edx  */
@@ -98,8 +110,10 @@ __pthread_cond_signal:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
 #if cond_lock != 0
        subq    $cond_lock, %rdi
@@ -109,8 +123,13 @@ __pthread_cond_signal:
        /* Unlock in loop requires wakeup.  */
 5:
        movq    %r8, %rdi
-       /* XYZ */
+#if cond_lock != 0
+       addq    $cond_lock, %rdi
+#endif
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     6b
        .size   __pthread_cond_signal, .-__pthread_cond_signal
index 003069f..a5de670 100644 (file)
@@ -23,6 +23,8 @@
 #include <lowlevelcond.h>
 #include <pthread-errnos.h>
 
+#include <kernel-features.h>
+
 /* For the calculation see asm/vsyscall.h.  */
 #define VSYSCALL_ADDR_vgettimeofday    0xffffffffff600000
 
@@ -186,12 +188,20 @@ __pthread_cond_timedwait:
        movl    %eax, (%rsp)
 
        leaq    24(%rsp), %r10
-#if FUTEX_WAIT == 0
-       xorl    %esi, %esi
+       cmpq    $-1, dep_mutex(%rdi)
+       movq    %r12, %rdx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAIT, %eax
+       movl    $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
 #else
-       movl    $FUTEX_WAIT, %esi
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+# if FUTEX_WAIT != 0
+       orl     $FUTEX_WAIT, %esi
+# endif
 #endif
-       movq    %r12, %rdx
        addq    $cond_futex, %rdi
        movl    $SYS_futex, %eax
        syscall
@@ -251,9 +261,19 @@ __pthread_cond_timedwait:
        jne     25f
 
        addq    $cond_nwaiters, %rdi
-       movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %esi
+       cmpq    $-1, dep_mutex-cond_nwaiters(%rdi)
        movl    $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE, %eax
+       movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE, %esi
+#endif
+       movl    $SYS_futex, %eax
        syscall
        subq    $cond_nwaiters, %rdi
 
@@ -292,8 +312,10 @@ __pthread_cond_timedwait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
        jmp     2b
 
@@ -302,8 +324,10 @@ __pthread_cond_timedwait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     4b
 
@@ -312,8 +336,10 @@ __pthread_cond_timedwait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
 #if cond_lock != 0
        subq    $cond_lock, %rdi
@@ -325,8 +351,10 @@ __pthread_cond_timedwait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     11b
 
@@ -344,8 +372,10 @@ __pthread_cond_timedwait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
 
 17:    movq    (%rsp), %rax
index 34ef2c7..2c17dc0 100644 (file)
@@ -23,6 +23,8 @@
 #include <lowlevelcond.h>
 #include <tcb-offsets.h>
 
+#include <kernel-features.h>
+
 
        .text
 
@@ -49,8 +51,10 @@ __condvar_cleanup:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
 #if cond_lock != 0
        subq    $cond_lock, %rdi
@@ -81,9 +85,19 @@ __condvar_cleanup:
        jne     4f
 
        addq    $cond_nwaiters, %rdi
-       movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %esi
+       cmpq    $-1, dep_mutex-cond_nwaiters(%rdi)
        movl    $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE, %eax
+       movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE, %esi
+#endif
+       movl    $SYS_futex, %eax
        syscall
        subq    $cond_nwaiters, %rdi
        movl    $1, %r12d
@@ -98,16 +112,28 @@ __condvar_cleanup:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
 
        /* Wake up all waiters to make sure no signal gets lost.  */
 2:     testq   %r12, %r12
        jnz     5f
        addq    $cond_futex, %rdi
-       movl    $FUTEX_WAKE, %esi
+       cmpq    $-1, dep_mutex-cond_futex(%rdi)
        movl    $0x7fffffff, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE, %eax
+       movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE, %esi
+#endif
        movl    $SYS_futex, %eax
        syscall
 
@@ -216,12 +242,20 @@ __pthread_cond_wait:
        xorq    %r10, %r10
        movq    %r12, %rdx
        addq    $cond_futex-cond_lock, %rdi
-       movl    $SYS_futex, %eax
-#if FUTEX_WAIT == 0
-       xorl    %esi, %esi
+       cmpq    $-1, dep_mutex-cond_futex(%rdi)
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAIT, %eax
+       movl    $(FUTEX_WAIT|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
 #else
-       movl    $FUTEX_WAIT, %esi
+       movl    $FUTEX_WAIT, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+# if FUTEX_WAIT != 0
+       orl     $FUTEX_WAIT, %esi
+# endif
 #endif
+       movl    $SYS_futex, %eax
        syscall
 
        movl    (%rsp), %edi
@@ -267,9 +301,19 @@ __pthread_cond_wait:
        jne     17f
 
        addq    $cond_nwaiters, %rdi
-       movl    $SYS_futex, %eax
-       movl    $FUTEX_WAKE, %esi
+       cmpq    $-1, dep_mutex-cond_nwaiters(%rdi)
        movl    $1, %edx
+#ifdef __ASSUME_PRIVATE_FUTEX
+       movl    $FUTEX_WAKE, %eax
+       movl    $(FUTEX_WAKE|FUTEX_PRIVATE_FLAG), %esi
+       cmove   %eax, %esi
+#else
+       movl    $0, %eax
+       movl    %fs:PRIVATE_FUTEX, %esi
+       cmove   %eax, %esi
+       orl     $FUTEX_WAKE, %esi
+#endif
+       movl    $SYS_futex, %eax
        syscall
        subq    $cond_nwaiters, %rdi
 
@@ -302,8 +346,10 @@ __pthread_cond_wait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
        jmp     2b
 
@@ -312,8 +358,10 @@ __pthread_cond_wait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     4b
 
@@ -322,8 +370,10 @@ __pthread_cond_wait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_lock_wait
 #if cond_lock != 0
        subq    $cond_lock, %rdi
@@ -335,8 +385,10 @@ __pthread_cond_wait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
        jmp     11b
 
@@ -354,8 +406,10 @@ __pthread_cond_wait:
 #if cond_lock != 0
        addq    $cond_lock, %rdi
 #endif
-       /* XYZ */
+       cmpq    $-1, dep_mutex-cond_lock(%rdi)
+       movl    $LLL_PRIVATE, %eax
        movl    $LLL_SHARED, %esi
+       cmovne  %eax, %esi
        callq   __lll_unlock_wake
 
 13:    movq    %r10, %rax
index 32a1077..7258107 100644 (file)
@@ -469,6 +469,13 @@ fail:
 }
 
 
+#ifdef O_CLOEXEC
+# define EXTRA_O_FLAGS O_CLOEXEC
+#else
+# define EXTRA_O_FLAGS 0
+#endif
+
+
 /* Initialize database information structures.  */
 void
 nscd_init (void)
@@ -491,7 +498,7 @@ nscd_init (void)
        if (dbs[cnt].persistent)
          {
            /* Try to open the appropriate file on disk.  */
-           int fd = open (dbs[cnt].db_filename, O_RDWR);
+           int fd = open (dbs[cnt].db_filename, O_RDWR | EXTRA_O_FLAGS);
            if (fd != -1)
              {
                struct stat64 st;
@@ -570,7 +577,8 @@ nscd_init (void)
                    /* We also need a read-only descriptor.  */
                    if (dbs[cnt].shared)
                      {
-                       dbs[cnt].ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
+                       dbs[cnt].ro_fd = open (dbs[cnt].db_filename,
+                                              O_RDONLY | EXTRA_O_FLAGS);
                        if (dbs[cnt].ro_fd == -1)
                          dbg_log (_("\
 cannot create read-only descriptor for \"%s\"; no mmap"),
@@ -607,22 +615,23 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
            if (dbs[cnt].persistent)
              {
                fd = open (dbs[cnt].db_filename,
-                          O_RDWR | O_CREAT | O_EXCL | O_TRUNC,
+                          O_RDWR | O_CREAT | O_EXCL | O_TRUNC | EXTRA_O_FLAGS,
                           S_IRUSR | S_IWUSR);
                if (fd != -1 && dbs[cnt].shared)
-                 ro_fd = open (dbs[cnt].db_filename, O_RDONLY);
+                 ro_fd = open (dbs[cnt].db_filename,
+                               O_RDONLY | EXTRA_O_FLAGS);
              }
            else
              {
                char fname[] = _PATH_NSCD_XYZ_DB_TMP;
-               fd = mkstemp (fname);
+               fd = mkostemp (fname, EXTRA_O_FLAGS);
 
                /* We do not need the file name anymore after we
                   opened another file descriptor in read-only mode.  */
                if (fd != -1)
                  {
                    if (dbs[cnt].shared)
-                     ro_fd = open (fname, O_RDONLY);
+                     ro_fd = open (fname, O_RDONLY | EXTRA_O_FLAGS);
 
                    unlink (fname);
                  }
@@ -741,6 +750,11 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
              }
          }
 
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+       /* We do not check here whether the O_CLOEXEC provided to the
+          open call was successful or not.  The two fcntl calls are
+          only performed once each per process start-up and therefore
+          is not noticeable at all.  */
        if (paranoia
            && ((dbs[cnt].wr_fd != -1
                 && fcntl (dbs[cnt].wr_fd, F_SETFD, FD_CLOEXEC) == -1)
@@ -752,6 +766,7 @@ cannot set socket to close on exec: %s; disabling paranoia mode"),
                     strerror (errno));
            paranoia = 0;
          }
+#endif
 
        if (dbs[cnt].head == NULL)
          {
index 23964b7..f2db529 100644 (file)
@@ -17,6 +17,8 @@
    Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 
 #include <alloca.h>
+#include <kernel-features.h>
+
 /* This file uses the getaddrinfo code but it compiles it without NSCD
    support.  We just need a few symbol renames.  */
 #define __inet_aton inet_aton
index 89e107b..d6bf51d 100644 (file)
@@ -24,6 +24,7 @@
 #include <netdb.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include <kernel-features.h>
 
 #include "nscd.h"
 #include "dbg_log.h"
index 320fbbd..f2ecadb 100644 (file)
@@ -1,4 +1,4 @@
-# Copyright (C) 1996,1997,1998,2000,2001,2002 Free Software Foundation, Inc.
+# Copyright (C) 1996-1998,2000,2001,2002,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
@@ -62,7 +62,8 @@ subdir-dirs = $(services:%=nss_%)
 vpath %.c $(subdir-dirs)
 
 
-libnss_files-routines  := $(addprefix files-,$(databases))
+libnss_files-routines  := $(addprefix files-,$(databases)) \
+                          files-have_o_cloexec
 distribute             += files-XXX.c files-parse.c
 
 
index fb13fbe..2149d1c 100644 (file)
@@ -1,5 +1,5 @@
 /* Common code for file-based databases in nss_files module.
-   Copyright (C) 1996-1999,2001,2002,2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-1999,2001,2002,2004,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
@@ -24,6 +24,8 @@
 #include <bits/libc-lock.h>
 #include "nsswitch.h"
 
+#include <kernel-features.h>
+
 /* These symbols are defined by the including source file:
 
    ENTNAME -- database name of the structure and functions (hostent, pwent).
@@ -74,29 +76,44 @@ internal_setent (int stayopen)
 
   if (stream == NULL)
     {
-      stream = fopen (DATAFILE, "r");
+      stream = fopen (DATAFILE, "re");
 
       if (stream == NULL)
        status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
       else
        {
-         /* We have to make sure the file is  `closed on exec'.  */
-         int result, flags;
-
-         result = flags = fcntl (fileno (stream), F_GETFD, 0);
-         if (result >= 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+         if (__have_o_cloexec <= 0)
+# endif
            {
-             flags |= FD_CLOEXEC;
-             result = fcntl (fileno (stream), F_SETFD, flags);
-           }
-         if (result < 0)
-           {
-             /* Something went wrong.  Close the stream and return a
-                failure.  */
-             fclose (stream);
-             stream = NULL;
-             status = NSS_STATUS_UNAVAIL;
+             /* We have to make sure the file is  `closed on exec'.  */
+             int result;
+             int flags;
+
+             result = flags = fcntl (fileno (stream), F_GETFD, 0);
+             if (result >= 0)
+               {
+# ifdef O_CLOEXEC
+                 if (__have_o_cloexec == 0)
+                   __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+                 if (__have_o_cloexec < 0)
+# endif
+                   {
+                     flags |= FD_CLOEXEC;
+                     result = fcntl (fileno (stream), F_SETFD, flags);
+                   }
+               }
+             if (result < 0)
+               {
+                 /* Something went wrong.  Close the stream and return a
+                    failure.  */
+                 fclose (stream);
+                 stream = NULL;
+                 status = NSS_STATUS_UNAVAIL;
+               }
            }
+#endif
        }
     }
   else
index c4717e1..57cc982 100644 (file)
@@ -1,5 +1,5 @@
 /* Mail alias file parser in nss_files module.
-   Copyright (C) 1996,97,98,99,2002,2006 Free Software Foundation, Inc.
+   Copyright (C) 1996,97,98,99,2002,2006,2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -27,6 +27,8 @@
 #include <stdio.h>
 #include <string.h>
 
+#include <kernel-features.h>
+
 #include "nsswitch.h"
 
 /* Locks the static variables in this file.  */
@@ -46,29 +48,44 @@ internal_setent (void)
 
   if (stream == NULL)
     {
-      stream = fopen ("/etc/aliases", "r");
+      stream = fopen ("/etc/aliases", "re");
 
       if (stream == NULL)
        status = errno == EAGAIN ? NSS_STATUS_TRYAGAIN : NSS_STATUS_UNAVAIL;
       else
        {
-         /* We have to make sure the file is  `closed on exec'.  */
-         int result, flags;
-
-         result = flags = fcntl (fileno (stream), F_GETFD, 0);
-         if (result >= 0)
-           {
-             flags |= FD_CLOEXEC;
-             result = fcntl (fileno (stream), F_SETFD, flags);
-           }
-         if (result < 0)
+#if !defined O_CLOEXEC || !defined __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+         if (__have_o_cloexec <= 0)
+# endif
            {
-             /* Something went wrong.  Close the stream and return a
-                failure.  */
-             fclose (stream);
-             stream = NULL;
-             status = NSS_STATUS_UNAVAIL;
+             /* We have to make sure the file is  `closed on exec'.  */
+             int result;
+             int flags;
+
+             result = flags = fcntl (fileno (stream), F_GETFD, 0);
+             if (result >= 0)
+               {
+# ifdef O_CLOEXEC
+                 if (__have_o_cloexec == 0)
+                   __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+                 if (__have_o_cloexec < 0)
+# endif
+                   {
+                     flags |= FD_CLOEXEC;
+                     result = fcntl (fileno (stream), F_SETFD, flags);
+                   }
+               }
+             if (result < 0)
+               {
+                 /* Something went wrong.  Close the stream and return a
+                    failure.  */
+                 fclose (stream);
+                 stream = NULL;
+                 status = NSS_STATUS_UNAVAIL;
+               }
            }
+#endif
        }
     }
   else
diff --git a/nss/nss_files/files-have_o_cloexec.c b/nss/nss_files/files-have_o_cloexec.c
new file mode 100644 (file)
index 0000000..a83e8a4
--- /dev/null
@@ -0,0 +1,24 @@
+/* Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include <fcntl.h>
+#include <kernel-features.h>
+
+#if defined O_CLOEXEC && !defined __ASSUME_O_CLOEXEC
+int __have_o_cloexec;
+#endif
index 67d9937..2770fb5 100644 (file)
@@ -1,5 +1,5 @@
 /* Handle locking of password file.
-   Copyright (C) 1996,98,2000,02 Free Software Foundation, Inc.
+   Copyright (C) 1996, 1998, 2000, 2002, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
 
@@ -26,6 +26,8 @@
 #include <unistd.h>
 #include <sys/file.h>
 
+#include <kernel-features.h>
+
 
 /* Name of the lock file.  */
 #define PWD_LOCKFILE "/etc/.pwd.lock"
@@ -96,20 +98,38 @@ __lckpwdf (void)
   /* Prevent problems caused by multiple threads.  */
   __libc_lock_lock (lock);
 
-  lock_fd = __open (PWD_LOCKFILE, O_WRONLY | O_CREAT, 0600);
+  int oflags = O_WRONLY | O_CREAT;
+#ifdef O_CLOEXEC
+  oflags |= O_CLOEXEC;
+#endif
+  lock_fd = __open (PWD_LOCKFILE, oflags, 0600);
   if (lock_fd == -1)
     /* Cannot create lock file.  */
     RETURN_CLOSE_FD (-1);
 
-  /* Make sure file gets correctly closed when process finished.  */
-  flags = __fcntl (lock_fd, F_GETFD, 0);
-  if (flags == -1)
-    /* Cannot get file flags.  */
-    RETURN_CLOSE_FD (-1);
-  flags |= FD_CLOEXEC;         /* Close on exit.  */
-  if (__fcntl (lock_fd, F_SETFD, flags) < 0)
-    /* Cannot set new flags.  */
-    RETURN_CLOSE_FD (-1);
+#ifndef __ASSUME_O_CLOEXEC
+# ifdef O_CLOEXEC
+  if (__have_o_cloexec <= 0)
+# endif
+    {
+      /* Make sure file gets correctly closed when process finished.  */
+      flags = __fcntl (lock_fd, F_GETFD, 0);
+      if (flags == -1)
+       /* Cannot get file flags.  */
+       RETURN_CLOSE_FD (-1);
+# ifdef O_CLOEXEC
+      if (__have_o_cloexec == 0)
+       __have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
+      if (__have_o_cloexec < 0)
+# endif
+       {
+         flags |= FD_CLOEXEC;          /* Close on exit.  */
+         if (__fcntl (lock_fd, F_SETFD, flags) < 0)
+           /* Cannot set new flags.  */
+           RETURN_CLOSE_FD (-1);
+       }
+    }
+#endif
 
   /* Now we have to get exclusive write access.  Since multiple
      process could try this we won't stop when it first fails.
index cd3dd40..c631d46 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-2000,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
@@ -34,7 +34,7 @@ tempnam (const char *dir, const char *pfx)
   if (__path_search (buf, FILENAME_MAX, dir, pfx, 1))
     return NULL;
 
-  if (__gen_tempname (buf, __GT_NOCREATE))
+  if (__gen_tempname (buf, 0, __GT_NOCREATE))
     return NULL;
 
   return __strdup (buf);
index 60c94d6..2c7bcde 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991, 92, 93, 95-98, 99 Free Software Foundation, Inc.
+/* Copyright (C) 1991, 92, 93, 95-98, 99, 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
@@ -47,8 +47,9 @@ stub_warning (__path_search)
  */
 
 int
-__gen_tempname (tmpl, kind)
+__gen_tempname (tmpl, flags, kind)
      char *tmpl;
+     int flags;
      int kind;
 {
   __set_errno (ENOSYS);
index 41f12bc..b900513 100644 (file)
@@ -1,5 +1,6 @@
 /* Open a stdio stream on an anonymous temporary file.  Generic/POSIX version.
-   Copyright (C) 1991,93,1996-2000,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1991,1993,1996-2000,2002,2003,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
@@ -17,6 +18,7 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
+#include <fcntl.h>
 #include <stdio.h>
 #include <unistd.h>
 
@@ -28,9 +30,6 @@
 # endif
 #endif
 
-#ifndef GEN_THIS
-# define GEN_THIS __GT_FILE
-#endif
 
 /* This returns a new stream opened on a temporary file (generated
    by tmpnam).  The file is opened with mode "w+b" (binary read/write).
@@ -45,7 +44,11 @@ tmpfile (void)
 
   if (__path_search (buf, FILENAME_MAX, NULL, "tmpf", 0))
     return NULL;
-  fd = __gen_tempname (buf, GEN_THIS);
+  int flags = 0;
+#ifdef FLAGS
+  flags = FLAGS;
+#endif
+  fd = __gen_tempname (buf, flags, __GT_FILE);
   if (fd < 0)
     return NULL;
 
@@ -59,7 +62,7 @@ tmpfile (void)
   return f;
 }
 
-#if defined USE_IN_LIBIO && GEN_THIS == __GT_FILE /* Not for tmpfile64.  */
+#if defined USE_IN_LIBIO && !defined FLAGS /* Not for tmpfile64.  */
 # undef tmpfile
 # include <shlib-compat.h>
 versioned_symbol (libc, __new_tmpfile, tmpfile, GLIBC_2_1);
index b265aee..ead3f50 100644 (file)
@@ -1,3 +1,3 @@
-#define GEN_THIS       __GT_BIGFILE
-#define tmpfile                tmpfile64
+#define FLAGS  O_LARGEFILE
+#define tmpfile        tmpfile64
 #include <tmpfile.c>
index 6b26f4f..f1c1644 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-1999,2000,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
@@ -39,7 +39,7 @@ tmpnam (char *s)
                        0))
     return NULL;
 
-  if (__builtin_expect (__gen_tempname (tmpbuf, __GT_NOCREATE), 0))
+  if (__builtin_expect (__gen_tempname (tmpbuf, 0, __GT_NOCREATE), 0))
     return NULL;
 
   if (s == NULL)
index 565a424..60c4286 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991,1993,1996-1999,2000 Free Software Foundation, Inc.
+/* Copyright (C) 1991,1993,1996-1999,2000,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
@@ -28,7 +28,7 @@ tmpnam_r (char *s)
 
   if (__path_search (s, L_tmpnam, NULL, NULL, 0))
     return NULL;
-  if (__gen_tempname (s, __GT_NOCREATE))
+  if (__gen_tempname (s, 0, __GT_NOCREATE))
     return NULL;
 
   return s;
index d475668..d405cbf 100644 (file)
@@ -614,6 +614,28 @@ extern int mkstemp64 (char *__template) __nonnull ((1)) __wur;
 extern char *mkdtemp (char *__template) __THROW __nonnull ((1)) __wur;
 #endif
 
+#ifdef __USE_GNU
+/* Generate a unique temporary file name from TEMPLATE similar to
+   mkstemp.  But allow the caller to pass additional flags which are
+   used in the open call to create the file..
+
+   This function is a possible cancellation points and therefore not
+   marked with __THROW.  */
+# ifndef __USE_FILE_OFFSET64
+extern int mkostemp (char *__template, int __flags) __nonnull ((1)) __wur;
+# else
+#  ifdef __REDIRECT
+extern int __REDIRECT (mkostemp, (char *__template, int __flags), mkostemp64)
+     __nonnull ((1)) __wur;
+#  else
+#   define mkostemp mkostemp64
+#  endif
+# endif
+# ifdef __USE_LARGEFILE64
+extern int mkostemp64 (char *__template, int __flags) __nonnull ((1)) __wur;
+# endif
+#endif
+
 
 __BEGIN_NAMESPACE_STD
 /* Execute the given line as a shell command.
index 9da8d6b..fadd5ec 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 1999, 2000, 2002, 2003, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Andreas Jaeger <aj@suse.de>, 1999.
 
@@ -35,6 +35,9 @@
 #define FLAG_MIPS64_LIBN32     0x0600
 #define FLAG_MIPS64_LIBN64     0x0700
 
+/* Name of auxiliary cache.  */
+#define _PATH_LDCONFIG_AUX_CACHE "/var/cache/ldconfig/aux-cache"
+
 /* Declared in cache.c.  */
 extern void print_cache (const char *cache_name);
 
@@ -45,10 +48,24 @@ extern void save_cache (const char *cache_name);
 extern void add_to_cache (const char *path, const char *lib, int flags,
                          unsigned int osversion, uint64_t hwcap);
 
+extern void init_aux_cache (void);
+
+extern void load_aux_cache (const char *aux_cache_name);
+
+extern int search_aux_cache (struct stat64 *stat_buf, int *flags,
+                            unsigned int *osversion, char **soname);
+
+extern void add_to_aux_cache (struct stat64 *stat_buf, int flags,
+                             unsigned int osversion, const char *soname);
+
+extern void save_aux_cache (const char *aux_cache_name);
+
 /* Declared in readlib.c.  */
 extern int process_file (const char *real_file_name, const char *file_name,
                         const char *lib, int *flag, unsigned int *osversion,
-                        char **soname, int is_link);
+                        char **soname, int is_link, struct stat64 *stat_buf);
+
+extern char *implicit_soname (const char *lib, int flag);
 
 /* Declared in readelflib.c.  */
 extern int process_elf_file (const char *file_name, const char *lib, int *flag,
index 06a73df..9e0b18e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1992,93,96,97,98,99,2001 Free Software Foundation, Inc.
+/* Copyright (C) 1992,93,96,97,98,99,2001,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
@@ -284,25 +284,30 @@ enum __ioctl_datum { IOC_8, IOC_16, IOC_32, IOC_64 };
 #define                ODDP            0x00000040      /* get/send odd parity */
 #define                EVENP           0x00000080      /* get/send even parity */
 #define                ANYP            0x000000c0      /* get any parity/send none */
-#define                NLDELAY         0x00000300      /* \n delay */
+#define                NLDLY           0x00000300      /* \n delay */
+#define                NLDELAY         NLDLY           /* traditional BSD name */
 #define                        NL0     0x00000000
 #define                        NL1     0x00000100      /* tty 37 */
 #define                        NL2     0x00000200      /* vt05 */
 #define                        NL3     0x00000300
-#define                TBDELAY         0x00000c00      /* horizontal tab delay */
+#define                TABDLY          0x00000c00      /* horizontal tab delay */
+#define                TBDELAY         TABDLY          /* traditional BSD name */
 #define                        TAB0    0x00000000
 #define                        TAB1    0x00000400      /* tty 37 */
 #define                        TAB2    0x00000800
 #define                XTABS           0x00000c00      /* expand tabs on output */
-#define                CRDELAY         0x00003000      /* \r delay */
+#define                CRDLY           0x00003000      /* \r delay */
+#define                CRDELAY         CRDLY           /* traditional BSD name */
 #define                        CR0     0x00000000
 #define                        CR1     0x00001000      /* tn 300 */
 #define                        CR2     0x00002000      /* tty 37 */
 #define                        CR3     0x00003000      /* concept 100 */
-#define                VTDELAY         0x00004000      /* vertical tab delay */
+#define                VTDLY           0x00004000      /* vertical tab delay */
+#define                VTDELAY         VTDLY           /* traditional BSD name */
 #define                        FF0     0x00000000
 #define                        FF1     0x00004000      /* tty 37 */
-#define                BSDELAY         0x00008000      /* \b delay */
+#define                BSDLY           0x00008000      /* \b delay */
+#define                BSDELAY         BSDLY           /* traditional BSD name */
 #define                        BS0     0x00000000
 #define                        BS1     0x00008000
 #define                ALLDELAY        (NLDELAY|TBDELAY|CRDELAY|VTDELAY|BSDELAY)
index c8973a0..eab658d 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1991-1999, 2000, 2001, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1991-2001, 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
@@ -37,9 +37,8 @@
 #endif
 #ifndef __GT_FILE
 # define __GT_FILE     0
-# define __GT_BIGFILE  1
-# define __GT_DIR      2
-# define __GT_NOCREATE 3
+# define __GT_DIR      1
+# define __GT_NOCREATE 2
 #endif
 
 #if STDC_HEADERS || _LIBC
@@ -220,12 +219,11 @@ static const char letters[] =
                        at the time of the call.
    __GT_FILE:          create the file using open(O_CREAT|O_EXCL)
                        and return a read-write fd.  The file is mode 0600.
-   __GT_BIGFILE:       same as __GT_FILE but use open64().
    __GT_DIR:           create a directory, which will be mode 0700.
 
    We use a clever algorithm to get hard-to-predict names. */
 int
-__gen_tempname (char *tmpl, int kind)
+__gen_tempname (char *tmpl, int flags, int kind)
 {
   int len;
   char *XXXXXX;
@@ -298,11 +296,9 @@ __gen_tempname (char *tmpl, int kind)
       switch (kind)
        {
        case __GT_FILE:
-         fd = __open (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
-         break;
-
-       case __GT_BIGFILE:
-         fd = __open64 (tmpl, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
+         fd = __open (tmpl,
+                      (flags & ~ACCESSPERMS)
+                      | O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR);
          break;
 
        case __GT_DIR:
index a93be63..f3f62cf 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1999-2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 1999-2004, 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
@@ -23,7 +23,7 @@
 #include <ldsodefs.h>
 
 
-#if HP_TIMING_AVAIL
+#if HP_TIMING_AVAIL && !defined HANDLED_CPUTIME
 /* Clock frequency of the processor.  We make it a 64-bit variable
    because some jokers are already playing with processors with more
    than 4GHz.  */
@@ -33,10 +33,8 @@ static hp_timing_t freq;
 /* This function is defined in the thread library.  */
 extern void __pthread_clock_settime (clockid_t clock_id, hp_timing_t offset)
      __attribute__ ((__weak__));
-#endif
 
 
-#if HP_TIMING_AVAIL
 static int
 hp_timing_settime (clockid_t clock_id, const struct timespec *tp)
 {
index 5afe20f..cd536a0 100644 (file)
@@ -1,5 +1,5 @@
 /* clock_gettime -- Get current time from a POSIX clockid_t.  Linux version.
-   Copyright (C) 2003,2004,2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 2003,2004,2005,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
@@ -133,11 +133,19 @@ maybe_syscall_gettime_cpu (clockid_t clock_id, struct timespec *tp)
        {
          if (e == EINVAL)
            {
+# ifdef HAVE_CLOCK_GETRES_VSYSCALL
              /* Check whether the kernel supports CPU clocks at all.
                 If not, record it for the future.  */
              r = INTERNAL_VSYSCALL (clock_getres, err, 2,
+                                    MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
+                                    NULL);
+# else
+             /* Check whether the kernel supports CPU clocks at all.
+                If not, record it for the future.  */
+             r = INTERNAL_SYSCALL (clock_getres, err, 2,
                                    MAKE_PROCESS_CPUCLOCK (0, CPUCLOCK_SCHED),
                                    NULL);
+# endif
              if (INTERNAL_SYSCALL_ERROR_P (r, err))
                __libc_missing_posix_cpu_timers = 1;
            }
index 89bad44..86c593e 100644 (file)
@@ -74,6 +74,7 @@ _dl_discover_osversion (void)
 #define ROUND(len) (((len) + sizeof note->n_type - 1) & -sizeof note->n_type)
                note = ((const void *) (note + 1)
                        + ROUND (note->n_namesz) + ROUND (note->n_descsz));
+#undef ROUND
              }
          }
     }
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.c b/sysdeps/unix/sysv/linux/dl-vdso.c
new file mode 100644 (file)
index 0000000..28d4bb1
--- /dev/null
@@ -0,0 +1,50 @@
+/* ELF symbol resolve functions for VDSO objects.
+   Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#include "config.h"
+#include <ldsodefs.h>
+
+
+void *
+internal_function
+_dl_vdso_vsym (const char *name, const struct r_found_version *vers)
+{
+  struct link_map *map = GLRO (dl_sysinfo_map);
+  void *value = NULL;
+
+
+  if (map != NULL)
+    {
+      /* Use a WEAK REF so we don't error out if the symbol is not found.  */
+      ElfW (Sym) wsym;
+      memset (&wsym, 0, sizeof (ElfW (Sym)));
+      wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
+
+      /* Search the scope of the vdso map.  */
+      const ElfW (Sym) *ref = &wsym;
+      lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
+                                                  map->l_local_scope,
+                                                  vers, 0, 0, NULL);
+
+      if (ref != NULL)
+       value = DL_SYMBOL_ADDRESS (result, ref);
+    }
+
+  return value;
+}
diff --git a/sysdeps/unix/sysv/linux/dl-vdso.h b/sysdeps/unix/sysv/linux/dl-vdso.h
new file mode 100644 (file)
index 0000000..7e433e0
--- /dev/null
@@ -0,0 +1,49 @@
+/* ELF symbol resolve functions for VDSO objects.
+   Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _DL_VDSO_H
+#define _DL_VDSO_H     1
+
+#include <assert.h>
+#include <ldsodefs.h>
+
+#ifdef NDEBUG
+# define CHECK_HASH(var) do {} while (0)
+#else
+# include <dl-hash.h>
+# define CHECK_HASH(var) assert (var.hash == _dl_elf_hash (var.name))
+#endif
+
+/* Create version number record for lookup.  */
+#define PREPARE_VERSION(var, vname, vhash) \
+  struct r_found_version var;                                                \
+  var.name = vname;                                                          \
+  var.hidden = 1;                                                            \
+  var.hash = vhash;                                                          \
+  CHECK_HASH (var);                                                          \
+  /* We don't have a specific file where the symbol can be found.  */        \
+  var.filename = NULL
+
+
+/* Functions for resolving symbols in the VDSO link map.  */
+extern void *_dl_vdso_vsym (const char *name,
+                           const struct r_found_version *version)
+     internal_function attribute_hidden;
+
+#endif /* dl-vdso.h */
index 48afd1f..79c9adc 100644 (file)
@@ -1,5 +1,6 @@
 /* Return information about the filesystem on which FD resides.
-   Copyright (C) 1996,1997,1998,1999,2000,2003 Free Software Foundation, Inc.
+   Copyright (C) 1996,1997,1998,1999,2000,2003,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
@@ -22,6 +23,7 @@
 #include <sys/statfs.h>
 #include <stddef.h>
 #include <sysdep.h>
+#include <kernel-features.h>
 
 /* Defined in statfs64.c.  */
 extern int __no_statfs64 attribute_hidden;
index c1c416a..1b9add4 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2005, 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
@@ -30,6 +30,7 @@
 #include <sysdep.h>
 #include <sys/syscall.h>
 #include <bp-checks.h>
+#include <kernel-features.h>
 
 #include <xstatconv.h>
 
index 72c60ec..34bc3c2 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004
+/* Copyright (C) 1996, 1997, 1998, 2000, 2001, 2003, 2004, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Jes Sorensen <jes@linuxcare.com>, July 2000
@@ -25,6 +25,8 @@
 #ifndef _BITS_SIGCONTEXT_H
 #define _BITS_SIGCONTEXT_H 1
 
+#define __need_size_t
+#include <stddef.h>
 #include <bits/sigstack.h>
 
 struct ia64_fpreg
index 66f0ac1..6bd6bda 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005
+/* Copyright (C) 1997, 1998, 1999, 2000, 2002, 2003, 2004, 2005, 2007
    Free Software Foundation, Inc.
    This file is part of the GNU C Library.
 
@@ -28,6 +28,7 @@
 #include <sys/ioctl.h>
 #include <bits/libc-lock.h>
 #include <not-cancel.h>
+#include <kernel-features.h>
 
 #include "netlinkaccess.h"
 
index 02e6935..9aa9aba 100644 (file)
@@ -33,6 +33,7 @@
 #include <sysdep.h>
 #include <time.h>
 #include <unistd.h>
+#include <kernel-features.h>
 
 #include "netlinkaccess.h"
 
index f8116d8..aab3df3 100644 (file)
 # define __ASSUME_TMPFS_NAME   1
 #endif
 
-/* 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 __x86_64__
+/* pselect/ppoll 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.  On x86_64 and SH this appeared first in 2.6.19-rc1,
+   on ia64 in 2.6.22-rc1 and on alpha just after 2.6.22-rc1.  */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+    && ((!defined __x86_64__ && !defined __sh__ && !defined __ia64__ \
+        && !defined __alpha__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020613 \
+           && (defined __x86_64__ || defined __sh__)) \
+       || (__LINUX_KERNEL_VERSION >= 0x020616 && defined __ia64__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
 # 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 __x86_64__
-# define __ASSUME_PPOLL        1
+# 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
+   the code.  On PPC they were introduced in 2.6.17-rc1, on SH in 2.6.19-rc1
+   and on Alpha just after 2.6.22-rc1.  */
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+    && ((!defined __sh__ && !defined __alpha__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
 # define __ASSUME_ATFCTS       1
 #endif
 
 /* Support for inter-process robust mutexes was added in 2.6.17.  */
-#if __LINUX_KERNEL_VERSION >= 0x020611
+#if __LINUX_KERNEL_VERSION >= 0x020611 \
+    && ((!defined __sh__ && !defined __alpha__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020613 && defined __sh__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020617 && defined __alpha__))
 # define __ASSUME_SET_ROBUST_LIST      1
 #endif
 
 # define __ASSUME_FUTEX_LOCK_PI        1
 #endif
 
-/* Support for utimensat syscall was added in 2.6.22.  */
-#if __LINUX_KERNEL_VERSION >= 0x020616
+/* Support for utimensat syscall was added in 2.6.22, on alpha and s390
+   only after 2.6.22-rc1.  */
+#if __LINUX_KERNEL_VERSION >= 0x020616 \
+    && ((!defined __sh__ && !defined __alpha__) \
+       || __LINUX_KERNEL_VERSION >= 0x020617)
 # define __ASSUME_UTIMENSAT    1
 #endif
 
 # define __ASSUME_PRIVATE_FUTEX        1
 #endif
 
-/* Support for fallocate was added in 2.6.23.  */
-#if __LINUX_KERNEL_VERSION >= 0x020617
+/* Support for fallocate was added in 2.6.23, on s390
+   only after 2.6.23-rc1.  */
+#if __LINUX_KERNEL_VERSION >= 0x020617 \
+    && ((!defined __s390__ && !defined __alpha__) \
+       || (__LINUX_KERNEL_VERSION >= 0x020618 && defined __s390__))
 # define __ASSUME_FALLOCATE    1
 #endif
index ecd8057..d1281cf 100644 (file)
@@ -8,5 +8,5 @@ gen-as-const-headers += ucontext_i.sym
 endif
 
 ifeq ($(subdir),elf)
-routines += dl-vdso
+sysdep_routines += dl-vdso
 endif
index f20a5a1..746d9ce 100644 (file)
@@ -23,7 +23,7 @@
 
 #ifdef SHARED
 
-extern void *__vdso_gettimeofday;
+extern void *__vdso_gettimeofday attribute_hidden;
 
 extern void *__vdso_clock_gettime;
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c b/sysdeps/unix/sysv/linux/powerpc/dl-vdso.c
deleted file mode 100644 (file)
index e1be097..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-/* ELF symbol resolve functions for VDSO objects.
-   Copyright (C) 2005 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
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#include "config.h"
-#include <dl-hash.h>
-#include <ldsodefs.h>
-
-
-void *
-internal_function
-_dl_vdso_vsym (const char *name, const char *version)
-{
-  struct link_map *map = GLRO (dl_sysinfo_map);
-  void *value = NULL;
-
-
-  if (map != NULL)
-    {
-      /* Use a WEAK REF so we don't error out if the symbol is not found.  */
-      ElfW (Sym) wsym;
-      memset (&wsym, 0, sizeof (ElfW (Sym)));
-      wsym.st_info = (unsigned char) ELFW (ST_INFO (STB_WEAK, STT_NOTYPE));
-
-      /* Compute hash value to the version string.  */
-      struct r_found_version vers;
-      vers.name = version;
-      vers.hidden = 1;
-      vers.hash = _dl_elf_hash (version);
-      /* We don't have a specific file where the symbol can be found.  */
-      vers.filename = NULL;
-
-      /* Search the scope of the vdso map.  */
-      const ElfW (Sym) *ref = &wsym;
-      lookup_t result = GLRO (dl_lookup_symbol_x) (name, map, &ref,
-                                                  map->l_local_scope,
-                                                  &vers, 0, 0, NULL);
-
-      if (ref != NULL)
-       value = DL_SYMBOL_ADDRESS (result, ref);
-    }
-
-  return value;
-}
diff --git a/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h b/sysdeps/unix/sysv/linux/powerpc/dl-vdso.h
deleted file mode 100644 (file)
index a7dcb2e..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-/* ELF symbol resolve functions for VDSO objects.
-   Copyright (C) 2005 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
-   modify it under the terms of the GNU Lesser General Public
-   License as published by the Free Software Foundation; either
-   version 2.1 of the License, or (at your option) any later version.
-
-   The GNU C Library is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-   Lesser General Public License for more details.
-
-   You should have received a copy of the GNU Lesser General Public
-   License along with the GNU C Library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
-   02111-1307 USA.  */
-
-#ifndef _DL_VDSO_H
-#define _DL_VDSO_H     1
-
-/* Functions for resolving symbols in the VDSO link map.  */
-extern void *_dl_vdso_vsym (const char *name, const char *version)
-     internal_function attribute_hidden;
-
-#endif /* dl-vdso.h */
index a71cfa5..d1f321c 100644 (file)
 #include <bp-start.h>
 #include <bp-sym.h>
 
-int __cache_line_size attribute_hidden;
-/* The main work is done in the generic function.  */
-#define LIBC_START_MAIN generic_start_main
-#define LIBC_START_DISABLE_INLINE
-#define LIBC_START_MAIN_AUXVEC_ARG
-#define MAIN_AUXVEC_ARG
-#define INIT_MAIN_ARGS
-#include <csu/libc-start.c>
-
-struct startup_info
-  {
-    void *__unbounded sda_base;
-    int (*main) (int, char **, char **, void *);
-    int (*init) (int, char **, char **, void *);
-    void (*fini) (void);
-  };
-
 
 #ifdef SHARED
 # include <sys/time.h>
@@ -50,27 +33,46 @@ struct startup_info
 # undef __clock_getres
 # include <bits/libc-vdso.h>
 
-void *__vdso_gettimeofday;
+void *__vdso_gettimeofday attribute_hidden;
 void *__vdso_clock_gettime;
 void *__vdso_clock_getres;
 void *__vdso_get_tbfreq;
 
-static inline void _libc_vdso_platform_setup (void)
-  {
-    __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday",
-                                        "LINUX_2.6.15");
+static inline void
+_libc_vdso_platform_setup (void)
+{
+  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
+
+  __vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
 
-    __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime",
-                                         "LINUX_2.6.15");
+  __vdso_clock_gettime = _dl_vdso_vsym ("__kernel_clock_gettime", &linux2615);
 
-    __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres",
-                                        "LINUX_2.6.15");
+  __vdso_clock_getres = _dl_vdso_vsym ("__kernel_clock_getres", &linux2615);
+
+  __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq", &linux2615);
+}
 
-    __vdso_get_tbfreq = _dl_vdso_vsym ("__kernel_vdso_get_tbfreq",
-                                      "LINUX_2.6.15");
-  }
+# define VDSO_SETUP _libc_vdso_platform_setup
 #endif
 
+
+int __cache_line_size attribute_hidden;
+/* The main work is done in the generic function.  */
+#define LIBC_START_MAIN generic_start_main
+#define LIBC_START_DISABLE_INLINE
+#define LIBC_START_MAIN_AUXVEC_ARG
+#define MAIN_AUXVEC_ARG
+#define INIT_MAIN_ARGS
+#include <csu/libc-start.c>
+
+struct startup_info
+  {
+    void *__unbounded sda_base;
+    int (*main) (int, char **, char **, void *);
+    int (*init) (int, char **, char **, void *);
+    void (*fini) (void);
+  };
+
 int
 /* GKM FIXME: GCC: this should get __BP_ prefix by virtue of the
    BPs in the arglist of startup_info.main and startup_info.init. */
@@ -117,10 +119,7 @@ int
        __cache_line_size = av->a_un.a_val;
        break;
       }
-#ifdef SHARED
-  /* Resolve and initialize function pointers for VDSO functions.  */
-  _libc_vdso_platform_setup ();
-#endif
+
   return generic_start_main (stinfo->main, argc, ubp_av, auxvec,
                             stinfo->init, stinfo->fini, rtld_fini,
                             stack_on_entry);
index cfc86ba..14eb311 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
 
 
 
 #ifdef __NR_ppoll
+# ifndef __ASSUME_PPOLL
 static int __generic_ppoll (struct pollfd *fds, nfds_t nfds,
                            const struct timespec *timeout,
                            const sigset_t *sigmask);
+# endif
 
 
 int
index 0dd744f..f39ee92 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2006.
 
 
 
 #ifdef __NR_pselect6
+# ifndef __ASSUME_PSELECT
 static int __generic_pselect (int nfds, fd_set *readfds, fd_set *writefds,
                              fd_set *exceptfds,
                              const struct timespec *timeout,
                              const sigset_t *sigmask);
+# endif
 
 
 int
index c0d7cd4..b2db542 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <kernel-features.h>
 
 #define EINVAL 22
 
index aba4ac3..4c3667a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2000, 2001 Free Software Foundation, Inc.
+/* Copyright (C) 2000, 2001, 2007 Free Software Foundation, Inc.
    Contributed by Martin Schwidefsky (schwidefsky@de.ibm.com).
    This file is part of the GNU C Library.
 
@@ -18,6 +18,7 @@
    02111-1307 USA.  */
 
 #include <sysdep.h>
+#include <kernel-features.h>
 
 #define EINVAL 22
 #define ENOSYS 38
index 0628427..92d22cf 100644 (file)
@@ -187,7 +187,7 @@ shm_open (const char *name, int oflag, mode_t mode)
 
          if (__builtin_expect (flags, 0) >= 0)
            {
-# ifndef O_CLOEXEC
+# ifdef O_CLOEXEC
              if (have_o_cloexec == 0)
                have_o_cloexec = (flags & FD_CLOEXEC) == 0 ? -1 : 1;
              if (have_o_cloexec < 0)
index 9f4c02c..71a51cc 100644 (file)
@@ -1,3 +1,5 @@
+#include <kernel-features.h>
+
 #include "../../i386/xstat.c"
 
 #ifdef __NR_stat64
index 9ccc7a7..c3d17b5 100644 (file)
@@ -1,5 +1,5 @@
 /* Return information about the filesystem on which FILE resides.
-   Copyright (C) 1996-2000,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1996-2000,2003,2004,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
@@ -22,6 +22,7 @@
 #include <sys/statfs.h>
 #include <stddef.h>
 #include <sysdep.h>
+#include <kernel-features.h>
 
 
 # if __ASSUME_STATFS64 == 0
index bdad506..6e2741a 100644 (file)
@@ -13,3 +13,7 @@ endif
 ifeq ($(subdir),csu)
 gen-as-const-headers += ucontext_i.sym
 endif
+
+ifeq ($(subdir),elf)
+sysdep_routines += dl-vdso
+endif
index fd1b3cc..34c100b 100644 (file)
@@ -6,4 +6,7 @@ libc {
 
     modify_ldt;
   }
+  GLIBC_PRIVATE {
+    __vdso_clock_gettime;
+  }
 }
diff --git a/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h b/sysdeps/unix/sysv/linux/x86_64/bits/libc-vdso.h
new file mode 100644 (file)
index 0000000..6e08d3b
--- /dev/null
@@ -0,0 +1,35 @@
+/* Resolve function pointers to VDSO functions.
+   Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifndef _LIBC_VDSO_H
+#define _LIBC_VDSO_H
+
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef SHARED
+
+extern int (*__vdso_gettimeofday) (struct timeval *, void *)
+  attribute_hidden;
+
+extern int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+#endif
+
+#endif /* _LIBC_VDSO_H */
index 84a99b0..f618e73 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 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
@@ -28,7 +28,12 @@ ENTRY (__gettimeofday)
        /* Align stack.  */
        sub     $0x8, %rsp
        cfi_adjust_cfa_offset(8)
+#ifdef SHARED
+       movq    __vdso_gettimeofday(%rip), %rax
+       PTR_DEMANGLE (%rax)
+#else
        movq    $VSYSCALL_ADDR_vgettimeofday, %rax
+#endif
        callq   *%rax
        /* Check error return.  */
        cmpl    $-4095, %eax
diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-start.c b/sysdeps/unix/sysv/linux/x86_64/libc-start.c
new file mode 100644 (file)
index 0000000..dea2e8a
--- /dev/null
@@ -0,0 +1,49 @@
+/* Copyright (C) 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
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, write to the Free
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
+
+#ifdef SHARED
+# include <dl-vdso.h>
+# include <bits/libc-vdso.h>
+
+int (*__vdso_gettimeofday) (struct timeval *, void *) attribute_hidden;
+
+int (*__vdso_clock_gettime) (clockid_t, struct timespec *);
+
+
+static inline void
+_libc_vdso_platform_setup (void)
+{
+  PREPARE_VERSION (linux26, "LINUX_2.6", 61765110);
+
+  void *p = _dl_vdso_vsym ("gettimeofday", &linux26);
+  /* If the vDSO is not available we fall back on the old vsyscall.  */
+#define VSYSCALL_ADDR_vgettimeofday    0xffffffffff600000ul
+  if (p == NULL)
+    p = (void *) VSYSCALL_ADDR_vgettimeofday;
+  PTR_MANGLE (p);
+  __vdso_gettimeofday = p;
+
+  p = _dl_vdso_vsym ("clock_gettime", &linux26);
+  PTR_MANGLE (p);
+  __vdso_clock_gettime = p;
+}
+
+# define VDSO_SETUP _libc_vdso_platform_setup
+#endif
+
+#include <csu/libc-start.c>
index 1d9a68a..44d5650 100644 (file)
 
 /* We don't want the label for the error handle to be global when we define
    it here.  */
-#ifdef PIC
-# define SYSCALL_ERROR_LABEL 0f
-#else
-# define SYSCALL_ERROR_LABEL syscall_error
-#endif
+# ifdef PIC
+#  define SYSCALL_ERROR_LABEL 0f
+# else
+#  define SYSCALL_ERROR_LABEL syscall_error
+# endif
 
-#undef PSEUDO
-#define        PSEUDO(name, syscall_name, args)                                      \
+# undef        PSEUDO
+# define PSEUDO(name, syscall_name, args)                                    \
   .text;                                                                     \
   ENTRY (name)                                                               \
     DO_CALL (syscall_name, args);                                            \
     jae SYSCALL_ERROR_LABEL;                                                 \
   L(pseudo_end):
 
-#undef PSEUDO_END
-#define        PSEUDO_END(name)                                                      \
+# undef        PSEUDO_END
+# define PSEUDO_END(name)                                                    \
   SYSCALL_ERROR_HANDLER                                                              \
   END (name)
 
-#undef PSEUDO_NOERRNO
-#define        PSEUDO_NOERRNO(name, syscall_name, args) \
+# undef        PSEUDO_NOERRNO
+# define PSEUDO_NOERRNO(name, syscall_name, args) \
   .text;                                                                     \
   ENTRY (name)                                                               \
     DO_CALL (syscall_name, args)
 
-#undef PSEUDO_END_NOERRNO
-#define        PSEUDO_END_NOERRNO(name) \
+# undef        PSEUDO_END_NOERRNO
+# define PSEUDO_END_NOERRNO(name) \
   END (name)
 
-#define ret_NOERRNO ret
+# define ret_NOERRNO ret
 
-#undef PSEUDO_ERRVAL
-#define        PSEUDO_ERRVAL(name, syscall_name, args) \
+# undef        PSEUDO_ERRVAL
+# define PSEUDO_ERRVAL(name, syscall_name, args) \
   .text;                                                                     \
   ENTRY (name)                                                               \
     DO_CALL (syscall_name, args);                                            \
     negq %rax
 
-#undef PSEUDO_END_ERRVAL
-#define        PSEUDO_END_ERRVAL(name) \
+# undef        PSEUDO_END_ERRVAL
+# define PSEUDO_END_ERRVAL(name) \
   END (name)
 
-#define ret_ERRVAL ret
+# define ret_ERRVAL ret
 
-#ifndef PIC
-#define SYSCALL_ERROR_HANDLER  /* Nothing here; code in sysdep.S is used.  */
-#elif RTLD_PRIVATE_ERRNO
-# define SYSCALL_ERROR_HANDLER                 \
+# ifndef PIC
+#  define SYSCALL_ERROR_HANDLER        /* Nothing here; code in sysdep.S is used.  */
+# elif RTLD_PRIVATE_ERRNO
+#  define SYSCALL_ERROR_HANDLER                        \
 0:                                             \
   leaq rtld_errno(%rip), %rcx;                 \
   xorl %edx, %edx;                             \
   movl %edx, (%rcx);                           \
   orq $-1, %rax;                               \
   jmp L(pseudo_end);
-#elif USE___THREAD
-# ifndef NOT_IN_libc
-#  define SYSCALL_ERROR_ERRNO __libc_errno
-# else
-#  define SYSCALL_ERROR_ERRNO errno
-# endif
-# define SYSCALL_ERROR_HANDLER                 \
+# elif USE___THREAD
+#  ifndef NOT_IN_libc
+#   define SYSCALL_ERROR_ERRNO __libc_errno
+#  else
+#   define SYSCALL_ERROR_ERRNO errno
+#  endif
+#  define SYSCALL_ERROR_HANDLER                        \
 0:                                             \
   movq SYSCALL_ERROR_ERRNO@GOTTPOFF(%rip), %rcx;\
   xorl %edx, %edx;                             \
   movl %edx, %fs:(%rcx);                       \
   orq $-1, %rax;                               \
   jmp L(pseudo_end);
-#elif defined _LIBC_REENTRANT
+# elif defined _LIBC_REENTRANT
 /* Store (- %rax) into errno through the GOT.
    Note that errno occupies only 4 bytes.  */
-# define SYSCALL_ERROR_HANDLER                 \
+#  define SYSCALL_ERROR_HANDLER                        \
 0:                                             \
   xorl %edx, %edx;                             \
   subq %rax, %rdx;                             \
 
 /* A quick note: it is assumed that the call to `__errno_location' does
    not modify the stack!  */
-#else /* Not _LIBC_REENTRANT.  */
-# define SYSCALL_ERROR_HANDLER                 \
+# else /* Not _LIBC_REENTRANT.  */
+#  define SYSCALL_ERROR_HANDLER                        \
 0:movq errno@GOTPCREL(%RIP), %rcx;             \
   xorl %edx, %edx;                             \
   subq %rax, %rdx;                             \
   movl %edx, (%rcx);                           \
   orq $-1, %rax;                               \
   jmp L(pseudo_end);
-#endif /* PIC */
+# endif        /* PIC */
 
 /* The Linux/x86-64 kernel expects the system call parameters in
    registers according to the following table:
 
     Syscalls of more than 6 arguments are not supported.  */
 
-#undef DO_CALL
-#define DO_CALL(syscall_name, args)            \
+# undef        DO_CALL
+# define DO_CALL(syscall_name, args)           \
     DOARGS_##args                              \
     movl $SYS_ify (syscall_name), %eax;                \
     syscall;
 
-#define DOARGS_0 /* nothing */
-#define DOARGS_1 /* nothing */
-#define DOARGS_2 /* nothing */
-#define DOARGS_3 /* nothing */
-#define DOARGS_4 movq %rcx, %r10;
-#define DOARGS_5 DOARGS_4
-#define DOARGS_6 DOARGS_5
+# define DOARGS_0 /* nothing */
+# define DOARGS_1 /* nothing */
+# define DOARGS_2 /* nothing */
+# define DOARGS_3 /* nothing */
+# define DOARGS_4 movq %rcx, %r10;
+# define DOARGS_5 DOARGS_4
+# define DOARGS_6 DOARGS_5
 
 #else  /* !__ASSEMBLER__ */
 /* Define a macro which expands inline into the wrapper code for a system
    call.  */
-#undef INLINE_SYSCALL
-#define INLINE_SYSCALL(name, nr, args...) \
+# undef INLINE_SYSCALL
+# define INLINE_SYSCALL(name, nr, args...) \
   ({                                                                         \
     unsigned long resultvar = INTERNAL_SYSCALL (name, , nr, args);           \
     if (__builtin_expect (INTERNAL_SYSCALL_ERROR_P (resultvar, ), 0))        \
       }                                                                              \
     (long) resultvar; })
 
-#undef INTERNAL_SYSCALL_DECL
-#define INTERNAL_SYSCALL_DECL(err) do { } while (0)
+# undef INTERNAL_SYSCALL_DECL
+# define INTERNAL_SYSCALL_DECL(err) do { } while (0)
 
-#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
+# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \
   ({                                                                         \
     unsigned long resultvar;                                                 \
     LOAD_ARGS_##nr (args)                                                    \
     : "=a" (resultvar)                                                       \
     : "0" (name) ASM_ARGS_##nr : "memory", "cc", "r11", "cx");               \
     (long) resultvar; })
-#undef INTERNAL_SYSCALL
-#define INTERNAL_SYSCALL(name, err, nr, args...) \
+# undef INTERNAL_SYSCALL
+# define INTERNAL_SYSCALL(name, err, nr, args...) \
   INTERNAL_SYSCALL_NCS (__NR_##name, err, nr, ##args)
 
-#undef INTERNAL_SYSCALL_ERROR_P
-#define INTERNAL_SYSCALL_ERROR_P(val, err) \
+# undef INTERNAL_SYSCALL_ERROR_P
+# define INTERNAL_SYSCALL_ERROR_P(val, err) \
   ((unsigned long) (val) >= -4095L)
 
-#undef INTERNAL_SYSCALL_ERRNO
-#define INTERNAL_SYSCALL_ERRNO(val, err)       (-(val))
+# undef INTERNAL_SYSCALL_ERRNO
+# define INTERNAL_SYSCALL_ERRNO(val, err)      (-(val))
+
+# ifdef SHARED
+#  define INLINE_VSYSCALL(name, nr, args...) \
+  ({                                                                         \
+    __label__ out;                                                           \
+    __label__ iserr;                                                         \
+    INTERNAL_SYSCALL_DECL (sc_err);                                          \
+    long int sc_ret;                                                         \
+                                                                             \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
+    PTR_DEMANGLE (vdsop);                                                    \
+    if (vdsop != NULL)                                                       \
+      {                                                                              \
+       sc_ret = vdsop (args);                                                \
+       if (!INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                       \
+         goto out;                                                           \
+       if (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err) != ENOSYS)                \
+         goto iserr;                                                         \
+      }                                                                              \
+                                                                             \
+    sc_ret = INTERNAL_SYSCALL (name, sc_err, nr, ##args);                    \
+    if (INTERNAL_SYSCALL_ERROR_P (sc_ret, sc_err))                           \
+      {                                                                              \
+      iserr:                                                                 \
+        __set_errno (INTERNAL_SYSCALL_ERRNO (sc_ret, sc_err));               \
+        sc_ret = -1L;                                                        \
+      }                                                                              \
+  out:                                                                       \
+    sc_ret;                                                                  \
+  })
+#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
+  ({                                                                         \
+    __label__ out;                                                           \
+    long int v_ret;                                                          \
+                                                                             \
+    __typeof (__vdso_##name) vdsop = __vdso_##name;                          \
+    PTR_DEMANGLE (vdsop);                                                    \
+    if (vdsop != NULL)                                                       \
+      {                                                                              \
+       v_ret = vdsop (args);                                                 \
+       if (!INTERNAL_SYSCALL_ERROR_P (v_ret, err)                            \
+           || INTERNAL_SYSCALL_ERRNO (v_ret, err) != ENOSYS)                 \
+         goto out;                                                           \
+      }                                                                              \
+    v_ret = INTERNAL_SYSCALL (name, err, nr, ##args);                        \
+  out:                                                                       \
+    v_ret;                                                                   \
+  })
+
+/* List of system calls which are supported as vsyscalls.  */
+#  define HAVE_CLOCK_GETTIME_VSYSCALL  1
+
+# else
+#  define INLINE_VSYSCALL(name, nr, args...) \
+  INLINE_SYSCALL (name, nr, ##args)
+#  define INTERNAL_VSYSCALL(name, err, nr, args...) \
+  INTERNAL_SYSCALL (name, err, nr, ##args)
+# endif
 
-#define LOAD_ARGS_0()
-#define LOAD_REGS_0
-#define ASM_ARGS_0
+# define LOAD_ARGS_0()
+# define LOAD_REGS_0
+# define ASM_ARGS_0
 
-#define LOAD_ARGS_1(a1)                                        \
+# define LOAD_ARGS_1(a1)                               \
   long int __arg1 = (long) (a1);                       \
   LOAD_ARGS_0 ()
-#define LOAD_REGS_1                                    \
+# define LOAD_REGS_1                                   \
   register long int _a1 asm ("rdi") = __arg1;          \
   LOAD_REGS_0
-#define ASM_ARGS_1     ASM_ARGS_0, "r" (_a1)
+# define ASM_ARGS_1    ASM_ARGS_0, "r" (_a1)
 
-#define LOAD_ARGS_2(a1, a2)                            \
+# define LOAD_ARGS_2(a1, a2)                           \
   long int __arg2 = (long) (a2);                       \
   LOAD_ARGS_1 (a1)
-#define LOAD_REGS_2                                    \
+# define LOAD_REGS_2                                   \
   register long int _a2 asm ("rsi") = __arg2;          \
   LOAD_REGS_1
-#define ASM_ARGS_2     ASM_ARGS_1, "r" (_a2)
+# define ASM_ARGS_2    ASM_ARGS_1, "r" (_a2)
 
-#define LOAD_ARGS_3(a1, a2, a3)                                \
+# define LOAD_ARGS_3(a1, a2, a3)                       \
   long int __arg3 = (long) (a3);                       \
   LOAD_ARGS_2 (a1, a2)
-#define LOAD_REGS_3                                    \
+# define LOAD_REGS_3                                   \
   register long int _a3 asm ("rdx") = __arg3;          \
   LOAD_REGS_2
-#define ASM_ARGS_3     ASM_ARGS_2, "r" (_a3)
+# define ASM_ARGS_3    ASM_ARGS_2, "r" (_a3)
 
-#define LOAD_ARGS_4(a1, a2, a3, a4)                    \
+# define LOAD_ARGS_4(a1, a2, a3, a4)                   \
   long int __arg4 = (long) (a4);                       \
   LOAD_ARGS_3 (a1, a2, a3)
-#define LOAD_REGS_4                                    \
+# define LOAD_REGS_4                                   \
   register long int _a4 asm ("r10") = __arg4;          \
   LOAD_REGS_3
-#define ASM_ARGS_4     ASM_ARGS_3, "r" (_a4)
+# define ASM_ARGS_4    ASM_ARGS_3, "r" (_a4)
 
-#define LOAD_ARGS_5(a1, a2, a3, a4, a5)                        \
+# define LOAD_ARGS_5(a1, a2, a3, a4, a5)               \
   long int __arg5 = (long) (a5);                       \
   LOAD_ARGS_4 (a1, a2, a3, a4)
-#define LOAD_REGS_5                                    \
+# define LOAD_REGS_5                                   \
   register long int _a5 asm ("r8") = __arg5;           \
   LOAD_REGS_4
-#define ASM_ARGS_5     ASM_ARGS_4, "r" (_a5)
+# define ASM_ARGS_5    ASM_ARGS_4, "r" (_a5)
 
-#define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)            \
+# define LOAD_ARGS_6(a1, a2, a3, a4, a5, a6)           \
   long int __arg6 = (long) (a6);                       \
   LOAD_ARGS_5 (a1, a2, a3, a4, a5)
-#define LOAD_REGS_6                                    \
+# define LOAD_REGS_6                                   \
   register long int _a6 asm ("r9") = __arg6;           \
   LOAD_REGS_5
-#define ASM_ARGS_6     ASM_ARGS_5, "r" (_a6)
+# define ASM_ARGS_6    ASM_ARGS_5, "r" (_a6)
 
 #endif /* __ASSEMBLER__ */
 
index 805e339..8210798 100644 (file)
@@ -1,5 +1,6 @@
 /* Convert between the kernel's `struct stat' format, and libc's.
-   Copyright (C) 1991,1995-1997,2000,2002,2003 Free Software Foundation, Inc.
+   Copyright (C) 1991,1995-1997,2000,2002,2003,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
@@ -20,6 +21,7 @@
 #include <errno.h>
 #include <sys/stat.h>
 #include <kernel_stat.h>
+#include <kernel-features.h>
 
 #ifdef STAT_IS_KERNEL_STAT