about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2007-05-15 20:34:30 +0000
committerRoland McGrath <roland@gnu.org>2007-05-15 20:34:30 +0000
commit18b86433d08e3df2a2820ede370d52bbda55eb74 (patch)
tree59347eb227c205dbf728f7177212f81a9ca48467
parente169ea9b569d9e9a60bde4aebe960591bacaf4ef (diff)
downloadglibc-18b86433d08e3df2a2820ede370d52bbda55eb74.tar.gz
glibc-18b86433d08e3df2a2820ede370d52bbda55eb74.tar.xz
glibc-18b86433d08e3df2a2820ede370d52bbda55eb74.zip
Updated to fedora-glibc-20070515T2025
-rw-r--r--ChangeLog45
-rw-r--r--README4
-rw-r--r--elf/dl-close.c58
-rw-r--r--elf/dl-open.c40
-rw-r--r--fedora/branch.mk4
-rw-r--r--include/features.h5
-rw-r--r--include/link.h10
-rw-r--r--malloc/arena.c3
-rw-r--r--malloc/hooks.c11
-rw-r--r--malloc/malloc.c54
-rw-r--r--nptl/ChangeLog16
-rw-r--r--nptl/TODO15
-rw-r--r--nptl/descr.h8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c8
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c14
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S19
-rw-r--r--nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S15
-rwxr-xr-xscripts/check-c++-types.sh4
-rw-r--r--sysdeps/unix/sysv/linux/Makefile2
-rw-r--r--sysdeps/unix/sysv/linux/sched_setaffinity.c12
-rw-r--r--sysdeps/unix/sysv/linux/tst-getcpu.c54
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c14
-rw-r--r--version.h4
23 files changed, 306 insertions, 113 deletions
diff --git a/ChangeLog b/ChangeLog
index 6a8b6dd1e3..d23f2efe96 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,50 @@
+2007-05-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* version.h (VERSION): Define to 6.
+	* include/features.h (__GLIBC_MINOR__): Likewise.
+
+	* malloc/malloc.c: Use all small bin slots on 64-bit archs.
+
+	* malloc/malloc.c (largebin_index): Really have 32 buckets with 64
+	sizes.
+
+2007-05-13  Ulrich Drepper  <drepper@redhat.com>
+
+	* malloc/malloc.c [MALLOC_DEBUG]: Keep track of current maximum
+	number of mmaps.  n_mmaps_max is the target.
+	* malloc/hooks.c: Likewise.
+	* malloc/arena.c: Likewise.
+
+2007-05-12  Andreas Jaeger  <aj@suse.de>
+
+	* sysdeps/unix/sysv/linux/tst-getcpu.c: Include <unistd.h> for
+	getpid.
+
+2007-05-11  Ulrich Drepper  <drepper@redhat.com>
+
+	* elf/dl-close.c (_dl_close_worker): Help gcc to optimize by
+	adding new variables.
+
+	* elf/dl-open.c (add_to_global): Introduce variable ns to help gcc
+	optimize.  Completely extend global scope array before making the
+	new entries visible.
+
 2007-05-10  Ulrich Drepper  <drepper@redhat.com>
 
+	* sysdeps/unix/sysv/linux/tst-getcpu.c: New file.
+	* sysdeps/unix/sysv/linux/Makefile [subdir=posix] (tests): Add
+	tst-getcpu.
+
+	* include/link.h: Move l_version and l_nversion members around to
+	fill gaps.
+
+	* scripts/check-c++-types.sh: Don't use -fnu89-inline option.
+
+	* sysdeps/unix/sysv/linux/sched_setaffinity.c
+	(__sched_setaffinity_new): If syscall was successful and
+	RESET_VGETCPU_CACHE is defined, use it before returning.
+	* sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c: New file.
+
 	* io/sys/stat.h: Make sure struct timespec is defined for
 	__USE_ATFILE.
 
diff --git a/README b/README
index 97b3a61e06..7b82d80e97 100644
--- a/README
+++ b/README
@@ -1,4 +1,4 @@
-This directory contains the version 2.5 release of the GNU C Library.
+This directory contains the version 2.6 release of the GNU C Library.
 
 The GNU C Library is the standard system C library for all GNU systems,
 and is an important part of what makes up a GNU system.  It provides the
@@ -52,7 +52,7 @@ The GNU C Library supports these configurations for using Linux kernels:
 
 The code for other CPU configurations supported by volunteers outside of
 the core glibc maintenance effort is contained in the separate `ports'
-add-on.  You can find glibc-ports-2.5 distributed separately in the
+add-on.  You can find glibc-ports-2.6 distributed separately in the
 same place where you got the main glibc distribution files.
 Currently these configurations are known to work using the `ports' add-on:
 
diff --git a/elf/dl-close.c b/elf/dl-close.c
index df968fe649..e0fe26ad02 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -1,5 +1,5 @@
 /* Close a shared object opened by `_dl_open'.
-   Copyright (C) 1996-2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-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
@@ -107,8 +107,6 @@ remove_slotinfo (size_t idx, struct dtv_slotinfo_list *listp, size_t disp,
 void
 _dl_close_worker (struct link_map *map)
 {
-  Lmid_t ns = map->l_ns;
-
   /* One less direct use.  */
   --map->l_direct_opencount;
 
@@ -131,11 +129,14 @@ _dl_close_worker (struct link_map *map)
       return;
     }
 
+  Lmid_t nsid = map->l_ns;
+  struct link_namespaces *ns = &GL(dl_ns)[nsid];
+
  retry:
   dl_close_state = pending;
 
   bool any_tls = false;
-  const unsigned int nloaded = GL(dl_ns)[ns]._ns_nloaded;
+  const unsigned int nloaded = ns->_ns_nloaded;
   char used[nloaded];
   char done[nloaded];
   struct link_map *maps[nloaded];
@@ -143,7 +144,7 @@ _dl_close_worker (struct link_map *map)
   /* Run over the list and assign indexes to the link maps and enter
      them into the MAPS array.  */
   int idx = 0;
-  for (struct link_map *l = GL(dl_ns)[ns]._ns_loaded; l != NULL; l = l->l_next)
+  for (struct link_map *l = ns->_ns_loaded; l != NULL; l = l->l_next)
     {
       l->l_idx = idx;
       maps[idx] = l;
@@ -220,11 +221,11 @@ _dl_close_worker (struct link_map *map)
     }
 
   /* Sort the entries.  */
-  _dl_sort_fini (GL(dl_ns)[ns]._ns_loaded, maps, nloaded, used, ns);
+  _dl_sort_fini (ns->_ns_loaded, maps, nloaded, used, nsid);
 
   /* Call all termination functions at once.  */
 #ifdef SHARED
-  bool do_audit = GLRO(dl_naudit) > 0 && !GL(dl_ns)[ns]._ns_loaded->l_auditing;
+  bool do_audit = GLRO(dl_naudit) > 0 && !ns->_ns_loaded->l_auditing;
 #endif
   bool unload_any = false;
   unsigned int first_loaded = ~0;
@@ -233,7 +234,7 @@ _dl_close_worker (struct link_map *map)
       struct link_map *imap = maps[i];
 
       /* All elements must be in the same namespace.  */
-      assert (imap->l_ns == ns);
+      assert (imap->l_ns == nsid);
 
       if (!used[i])
 	{
@@ -248,7 +249,7 @@ _dl_close_worker (struct link_map *map)
 	      if (__builtin_expect (GLRO(dl_debug_mask) & DL_DEBUG_IMPCALLS,
 				    0))
 		_dl_debug_printf ("\ncalling fini: %s [%lu]\n\n",
-				  imap->l_name, ns);
+				  imap->l_name, nsid);
 
 	      if (imap->l_info[DT_FINI_ARRAY] != NULL)
 		{
@@ -334,7 +335,7 @@ _dl_close_worker (struct link_map *map)
 		struct link_map *tmap = (struct link_map *)
 		  ((char *) imap->l_scope[cnt]
 		   - offsetof (struct link_map, l_searchlist));
-		assert (tmap->l_ns == ns);
+		assert (tmap->l_ns == nsid);
 		if (tmap->l_idx == IDX_STILL_USED)
 		  ++remain;
 		else
@@ -435,7 +436,7 @@ _dl_close_worker (struct link_map *map)
   /* Auditing checkpoint: we will start deleting objects.  */
   if (__builtin_expect (do_audit, 0))
     {
-      struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
+      struct link_map *head = ns->_ns_loaded;
       struct audit_ifaces *afct = GLRO(dl_audit);
       /* Do not call the functions for any auditing object.  */
       if (head->l_auditing == 0)
@@ -452,7 +453,7 @@ _dl_close_worker (struct link_map *map)
 #endif
 
   /* Notify the debugger we are about to remove some loaded objects.  */
-  struct r_debug *r = _dl_debug_initialize (0, ns);
+  struct r_debug *r = _dl_debug_initialize (0, nsid);
   r->r_state = RT_DELETE;
   _dl_debug_state ();
 
@@ -474,19 +475,18 @@ _dl_close_worker (struct link_map *map)
 	  if (__builtin_expect (imap->l_global, 0))
 	    {
 	      /* This object is in the global scope list.  Remove it.  */
-	      unsigned int cnt = GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
+	      struct r_scope_elem *ns_msl = ns->_ns_main_searchlist;
+	      unsigned int cnt = ns_msl->r_nlist;
 
 	      do
 		--cnt;
-	      while (GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt] != imap);
+	      while (ns_msl->r_list[cnt] != imap);
 
 	      /* The object was already correctly registered.  */
-	      while (++cnt
-		     < GL(dl_ns)[ns]._ns_main_searchlist->r_nlist)
-		GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt - 1]
-		  = GL(dl_ns)[ns]._ns_main_searchlist->r_list[cnt];
+	      while (++cnt < ns_msl->r_nlist)
+		ns_msl->r_list[cnt - 1] = ns_msl->r_list[cnt];
 
-	      --GL(dl_ns)[ns]._ns_main_searchlist->r_nlist;
+	      --ns_msl->r_nlist;
 	    }
 
 	  /* Remove the object from the dtv slotinfo array if it uses TLS.  */
@@ -581,12 +581,12 @@ _dl_close_worker (struct link_map *map)
 	  else
 	    {
 #ifdef SHARED
-	      assert (ns != LM_ID_BASE);
+	      assert (nsid != LM_ID_BASE);
 #endif
-	      GL(dl_ns)[ns]._ns_loaded = imap->l_next;
+	      ns->_ns_loaded = imap->l_next;
 	    }
 
-	  --GL(dl_ns)[ns]._ns_nloaded;
+	  --ns->_ns_nloaded;
 	  if (imap->l_next != NULL)
 	    imap->l_next->l_prev = imap->l_prev;
 
@@ -648,7 +648,7 @@ _dl_close_worker (struct link_map *map)
   /* Auditing checkpoint: we have deleted all objects.  */
   if (__builtin_expect (do_audit, 0))
     {
-      struct link_map *head = GL(dl_ns)[ns]._ns_loaded;
+      struct link_map *head = ns->_ns_loaded;
       /* Do not call the functions for any auditing object.  */
       if (head->l_auditing == 0)
 	{
@@ -732,22 +732,22 @@ free_slotinfo (struct dtv_slotinfo_list **elemp)
 
 libc_freeres_fn (free_mem)
 {
-  for (Lmid_t ns = 0; ns < DL_NNS; ++ns)
-    if (__builtin_expect (GL(dl_ns)[ns]._ns_global_scope_alloc, 0) != 0
-	&& (GL(dl_ns)[ns]._ns_main_searchlist->r_nlist
+  for (Lmid_t nsid = 0; nsid < DL_NNS; ++nsid)
+    if (__builtin_expect (GL(dl_ns)[nsid]._ns_global_scope_alloc, 0) != 0
+	&& (GL(dl_ns)[nsid]._ns_main_searchlist->r_nlist
 	    // XXX Check whether we need NS-specific initial_searchlist
 	    == GLRO(dl_initial_searchlist).r_nlist))
       {
 	/* All object dynamically loaded by the program are unloaded.  Free
 	   the memory allocated for the global scope variable.  */
-	struct link_map **old = GL(dl_ns)[ns]._ns_main_searchlist->r_list;
+	struct link_map **old = GL(dl_ns)[nsid]._ns_main_searchlist->r_list;
 
 	/* Put the old map in.  */
-	GL(dl_ns)[ns]._ns_main_searchlist->r_list
+	GL(dl_ns)[nsid]._ns_main_searchlist->r_list
 	  // XXX Check whether we need NS-specific initial_searchlist
 	  = GLRO(dl_initial_searchlist).r_list;
 	/* Signal that the original map is used.  */
-	GL(dl_ns)[ns]._ns_global_scope_alloc = 0;
+	GL(dl_ns)[nsid]._ns_global_scope_alloc = 0;
 
 	/* Now free the old map.  */
 	free (old);
diff --git a/elf/dl-open.c b/elf/dl-open.c
index 259372178b..583878781e 100644
--- a/elf/dl-open.c
+++ b/elf/dl-open.c
@@ -1,5 +1,5 @@
 /* Load a shared object at runtime, relocate it, and run its initializer.
-   Copyright (C) 1996-2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1996-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
@@ -97,17 +97,17 @@ add_to_global (struct link_map *new)
      in an realloc() call.  Therefore we allocate a completely new
      array the first time we have to add something to the locale scope.  */
 
-  if (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc == 0)
+  struct link_namespaces *ns = &GL(dl_ns)[new->l_ns];
+  if (ns->_ns_global_scope_alloc == 0)
     {
       /* This is the first dynamic object given global scope.  */
-      GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
-	= GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add + 8;
+      ns->_ns_global_scope_alloc
+	= ns->_ns_main_searchlist->r_nlist + to_add + 8;
       new_global = (struct link_map **)
-	malloc (GL(dl_ns)[new->l_ns]._ns_global_scope_alloc
-		* sizeof (struct link_map *));
+	malloc (ns->_ns_global_scope_alloc * sizeof (struct link_map *));
       if (new_global == NULL)
 	{
-	  GL(dl_ns)[new->l_ns]._ns_global_scope_alloc = 0;
+	  ns->_ns_global_scope_alloc = 0;
 	nomem:
 	  _dl_signal_error (ENOMEM, new->l_libname->name, NULL,
 			    N_("cannot extend global scope"));
@@ -115,29 +115,29 @@ add_to_global (struct link_map *new)
 	}
 
       /* Copy over the old entries.  */
-      GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list
-	= memcpy (new_global,
-		  GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
-		  (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist
+      ns->_ns_main_searchlist->r_list
+	= memcpy (new_global, ns->_ns_main_searchlist->r_list,
+		  (ns->_ns_main_searchlist->r_nlist
 		   * sizeof (struct link_map *)));
     }
-  else if (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist + to_add
-	   > GL(dl_ns)[new->l_ns]._ns_global_scope_alloc)
+  else if (ns->_ns_main_searchlist->r_nlist + to_add
+	   > ns->_ns_global_scope_alloc)
     {
       /* We have to extend the existing array of link maps in the
 	 main map.  */
       new_global = (struct link_map **)
-	realloc (GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list,
-		 ((GL(dl_ns)[new->l_ns]._ns_global_scope_alloc + to_add + 8)
+	realloc (ns->_ns_main_searchlist->r_list,
+		 ((ns->_ns_global_scope_alloc + to_add + 8)
 		  * sizeof (struct link_map *)));
       if (new_global == NULL)
 	goto nomem;
 
-      GL(dl_ns)[new->l_ns]._ns_global_scope_alloc += to_add + 8;
-      GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list = new_global;
+      ns->_ns_global_scope_alloc += to_add + 8;
+      ns->_ns_main_searchlist->r_list = new_global;
     }
 
   /* Now add the new entries.  */
+  unsigned int new_nlist = ns->_ns_main_searchlist->r_nlist;
   for (cnt = 0; cnt < new->l_searchlist.r_nlist; ++cnt)
     {
       struct link_map *map = new->l_searchlist.r_list[cnt];
@@ -145,11 +145,11 @@ add_to_global (struct link_map *new)
       if (map->l_global == 0)
 	{
 	  map->l_global = 1;
-	  GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_list[GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist]
-	    = map;
-	  ++GL(dl_ns)[new->l_ns]._ns_main_searchlist->r_nlist;
+	  ns->_ns_main_searchlist->r_list[new_nlist++] = map;
 	}
     }
+  atomic_write_barrier ();
+  ns->_ns_main_searchlist->r_nlist = new_nlist;
 
   return 0;
 }
diff --git a/fedora/branch.mk b/fedora/branch.mk
index b38bb1790c..f04611d44b 100644
--- a/fedora/branch.mk
+++ b/fedora/branch.mk
@@ -3,5 +3,5 @@ glibc-branch := fedora
 glibc-base := HEAD
 DIST_BRANCH := devel
 COLLECTION := dist-fc7
-fedora-sync-date := 2007-05-10 23:08 UTC
-fedora-sync-tag := fedora-glibc-20070510T2308
+fedora-sync-date := 2007-05-15 20:25 UTC
+fedora-sync-tag := fedora-glibc-20070515T2025
diff --git a/include/features.h b/include/features.h
index 4eb49a92b1..0fd14d2563 100644
--- a/include/features.h
+++ b/include/features.h
@@ -1,5 +1,4 @@
-/* Copyright (C) 1991,1992,1993,1995,1996,1997,1998,1999,2000,2001,2002,2003,2004,2005,2006
-	Free Software Foundation, Inc.
+/* Copyright (C) 1991,1992,1993,1995-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
@@ -310,7 +309,7 @@
 /* Major and minor version number of the GNU C library package.  Use
    these macros to test for features in specific releases.  */
 #define	__GLIBC__	2
-#define	__GLIBC_MINOR__	5
+#define	__GLIBC_MINOR__	6
 
 #define __GLIBC_PREREQ(maj, min) \
 	((__GLIBC__ << 16) + __GLIBC_MINOR__ >= ((maj) << 16) + (min))
diff --git a/include/link.h b/include/link.h
index b45deabf7f..67d70470d1 100644
--- a/include/link.h
+++ b/include/link.h
@@ -1,6 +1,6 @@
 /* Data structure for communication from the run-time dynamic linker for
    loaded ELF shared objects.
-   Copyright (C) 1995-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 1995-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
@@ -141,6 +141,10 @@ struct link_map
     /* Dependent object that first caused this object to be loaded.  */
     struct link_map *l_loader;
 
+    /* Array with version names.  */
+    struct r_found_version *l_versions;
+    unsigned int l_nversions;
+
     /* Symbol hash table.  */
     Elf_Symndx l_nbuckets;
     Elf32_Word l_gnu_bitmask_idxbits;
@@ -184,10 +188,6 @@ struct link_map
     unsigned int l_removed:1;	/* Nozero if the object cannot be used anymore
 				   since it is removed.  */
 
-    /* Array with version names.  */
-    unsigned int l_nversions;
-    struct r_found_version *l_versions;
-
     /* Collected information about own RPATH directories.  */
     struct r_search_path_struct l_rpath_dirs;
 
diff --git a/malloc/arena.c b/malloc/arena.c
index ce64335567..9e3ff47347 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -370,6 +370,9 @@ ptmalloc_init_minimal (void)
   mp_.top_pad        = DEFAULT_TOP_PAD;
 #endif
   mp_.n_mmaps_max    = DEFAULT_MMAP_MAX;
+#if MALLOC_DEBUG
+  mp_.n_mmaps_cmax   = DEFAULT_MMAP_MAX;
+#endif
   mp_.mmap_threshold = DEFAULT_MMAP_THRESHOLD;
   mp_.trim_threshold = DEFAULT_TRIM_THRESHOLD;
   mp_.pagesize       = malloc_getpagesize;
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 8346e73453..cde3e18cbd 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -1,5 +1,5 @@
 /* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 2001,2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+   Copyright (C) 2001-2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
 
@@ -507,6 +507,9 @@ struct malloc_save_state {
   unsigned long trim_threshold;
   unsigned long top_pad;
   unsigned int  n_mmaps_max;
+#if MALLOC_DEBUG
+  unsigned int  n_mmaps_cmax;
+#endif
   unsigned long mmap_threshold;
   int           check_action;
   unsigned long max_sbrked_mem;
@@ -550,6 +553,9 @@ public_gET_STATe(void)
   ms->trim_threshold = mp_.trim_threshold;
   ms->top_pad = mp_.top_pad;
   ms->n_mmaps_max = mp_.n_mmaps_max;
+#if MALLOC_DEBUG
+  ms->n_mmaps_cmax = mp_.n_mmaps_cmax;
+#endif
   ms->mmap_threshold = mp_.mmap_threshold;
   ms->check_action = check_action;
   ms->max_sbrked_mem = main_arena.max_system_mem;
@@ -621,6 +627,9 @@ public_sET_STATe(Void_t* msptr)
   mp_.trim_threshold = ms->trim_threshold;
   mp_.top_pad = ms->top_pad;
   mp_.n_mmaps_max = ms->n_mmaps_max;
+#if MALLOC_DEBUG
+  mp_.n_mmaps_cmax = ms->n_mmaps_cmax;
+#endif
   mp_.mmap_threshold = ms->mmap_threshold;
   check_action = ms->check_action;
   main_arena.max_system_mem = ms->max_sbrked_mem;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 8ae941c597..e061db94d6 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2125,22 +2125,37 @@ typedef struct malloc_chunk* mbinptr;
 
 #define NBINS             128
 #define NSMALLBINS         64
-#define SMALLBIN_WIDTH      8
-#define MIN_LARGE_SIZE    512
+#define SMALLBIN_WIDTH    MALLOC_ALIGNMENT
+#define MIN_LARGE_SIZE    (NSMALLBINS * SMALLBIN_WIDTH)
 
 #define in_smallbin_range(sz)  \
   ((unsigned long)(sz) < (unsigned long)MIN_LARGE_SIZE)
 
-#define smallbin_index(sz)     (((unsigned)(sz)) >> 3)
+#define smallbin_index(sz) \
+  (SMALLBIN_WIDTH == 16 ? (((unsigned)(sz)) >> 4) : (((unsigned)(sz)) >> 3))
 
-#define largebin_index(sz)                                                   \
-(((((unsigned long)(sz)) >>  6) <= 32)?  56 + (((unsigned long)(sz)) >>  6): \
+#define largebin_index_32(sz)                                                \
+(((((unsigned long)(sz)) >>  6) <= 38)?  56 + (((unsigned long)(sz)) >>  6): \
  ((((unsigned long)(sz)) >>  9) <= 20)?  91 + (((unsigned long)(sz)) >>  9): \
  ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \
  ((((unsigned long)(sz)) >> 15) <=  4)? 119 + (((unsigned long)(sz)) >> 15): \
  ((((unsigned long)(sz)) >> 18) <=  2)? 124 + (((unsigned long)(sz)) >> 18): \
                                         126)
 
+// XXX It remains to be seen whether it is good to keep the widths of
+// XXX the buckets the same or whether it should be scaled by a factor
+// XXX of two as well.
+#define largebin_index_64(sz)                                                \
+(((((unsigned long)(sz)) >>  6) <= 48)?  48 + (((unsigned long)(sz)) >>  6): \
+ ((((unsigned long)(sz)) >>  9) <= 20)?  91 + (((unsigned long)(sz)) >>  9): \
+ ((((unsigned long)(sz)) >> 12) <= 10)? 110 + (((unsigned long)(sz)) >> 12): \
+ ((((unsigned long)(sz)) >> 15) <=  4)? 119 + (((unsigned long)(sz)) >> 15): \
+ ((((unsigned long)(sz)) >> 18) <=  2)? 124 + (((unsigned long)(sz)) >> 18): \
+                                        126)
+
+#define largebin_index(sz) \
+  (SIZE_SZ == 8 ? largebin_index_64 (sz) : largebin_index_32 (sz))
+
 #define bin_index(sz) \
  ((in_smallbin_range(sz)) ? smallbin_index(sz) : largebin_index(sz))
 
@@ -2343,6 +2358,9 @@ struct malloc_par {
   /* Memory map support */
   int              n_mmaps;
   int              n_mmaps_max;
+#if MALLOC_DEBUG
+  int              n_mmaps_cmax;
+#endif
   int              max_n_mmaps;
   /* the mmap_threshold is dynamic, until the user sets
      it manually, at which point we need to disable any
@@ -2858,7 +2876,8 @@ static void do_check_malloc_state(mstate av)
   assert(total <= (unsigned long)(mp_.max_total_mem));
   assert(mp_.n_mmaps >= 0);
 #endif
-  assert(mp_.n_mmaps <= mp_.n_mmaps_max);
+  assert(mp_.n_mmaps <= mp_.n_mmaps_cmax);
+  assert(mp_.n_mmaps_max <= mp_.n_mmaps_cmax);
   assert(mp_.n_mmaps <= mp_.max_n_mmaps);
 
   assert((unsigned long)(av->system_mem) <=
@@ -3456,6 +3475,13 @@ munmap_chunk(p) mchunkptr p;
     }
 
   mp_.n_mmaps--;
+#if MALLOC_DEBUG
+  if (mp_.n_mmaps_cmax > mp_.n_mmaps_max)
+    {
+      assert (mp_.n_mmaps_cmax == mp_.n_mmaps + 1);
+      mp_.n_mmaps_cmax = mp_.n_mmaps;
+    }
+#endif
   mp_.mmapped_mem -= total_size;
 
   int ret __attribute__ ((unused)) = munmap((char *)block, total_size);
@@ -5371,6 +5397,9 @@ mstate av; size_t n_elements; size_t* sizes; int opts; Void_t* chunks[];
   mp_.n_mmaps_max = 0;
   mem = _int_malloc(av, size);
   mp_.n_mmaps_max = mmx;   /* reset mmap */
+#if MALLOC_DEBUG
+  mp_.n_mmaps_cmax = mmx;
+#endif
   if (mem == 0)
     return 0;
 
@@ -5696,8 +5725,17 @@ int mALLOPt(param_number, value) int param_number; int value;
       res = 0;
     else
 #endif
-      mp_.n_mmaps_max = value;
-      mp_.no_dyn_threshold = 1;
+      {
+#if MALLOC_DEBUG
+	if (mp_.n_mmaps <= value)
+	  mp_.n_mmaps_cmax = value;
+	else
+	  mp_.n_mmaps_cmax = mp_.n_mmaps;
+#endif
+
+	mp_.n_mmaps_max = value;
+	mp_.no_dyn_threshold = 1;
+      }
     break;
 
   case M_CHECK_ACTION:
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index 662c567c8b..0671f4a459 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,19 @@
+2007-05-14  Ulrich Drepper  <drepper@redhat.com>
+
+	* sysdeps/unix/sysv/linux/x86_64/sem_wait.S: Remove unnecessary
+	extra cancellation test.
+	* sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S: Likewise.
+
+2007-05-10  Ulrich Drepper  <drepper@redhat.com>
+
+	* descr.h (struct pthread): Rearrange members to fill hole in
+	64-bit layout.
+
+	* sysdeps/unix/sysv/linux/pthread_setaffinity.c
+	(__pthread_setaffinity_new): If syscall was successful and
+	RESET_VGETCPU_CACHE is defined, use it before returning.
+	* sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c: New file.
+
 2007-05-10  Jakub Jelinek  <jakub@redhat.com>
 
 	[BZ #4455]
diff --git a/nptl/TODO b/nptl/TODO
index d597176512..70b8fe4f76 100644
--- a/nptl/TODO
+++ b/nptl/TODO
@@ -14,3 +14,18 @@ syscall needed.
 
 - test with threaded process terminating and semadj (?) being applied
   only after all threads are gone
+
+
+
+- semaphore changes:
+
+  - sem_post should only wake one thread and only when the state of
+    the semaphore changed from 0 to 1
+
+    this also requires that sem_wait and sem_timedwait don't drop the
+    post if they get canceled.
+
+  - possibly add counter field.  This requires reviving the
+    differences between old and new semaphose funtions.  The old ones
+    stay as they are now.  The new once can use an additional field
+    wich is the counter for the number of waiters
diff --git a/nptl/descr.h b/nptl/descr.h
index 321ce85085..00cad1aa83 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2002-2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -268,6 +268,9 @@ struct pthread
 	       | EXITING_BITMASK | CANCEL_RESTMASK | TERMINATED_BITMASK))     \
    == (CANCELTYPE_BITMASK | CANCELED_BITMASK))
 
+  /* Flags.  Including those copied from the thread attribute.  */
+  int flags;
+
   /* We allocate one block of references here.  This should be enough
      to avoid allocating any memory dynamically for most applications.  */
   struct pthread_key_data
@@ -321,9 +324,6 @@ struct pthread
   /* Check whether a thread is detached.  */
 #define IS_DETACHED(pd) ((pd)->joinid == (pd))
 
-  /* Flags.  Including those copied from the thread attribute.  */
-  int flags;
-
   /* The result of the thread function.  */
   void *result;
 
diff --git a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
index 3776e26e4b..fa0f46feec 100644
--- a/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
+++ b/nptl/sysdeps/unix/sysv/linux/pthread_setaffinity.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2003, 2004, 2006 Free Software Foundation, Inc.
+/* Copyright (C) 2003, 2004, 2006, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
 
@@ -79,6 +79,12 @@ __pthread_setaffinity_new (pthread_t th, size_t cpusetsize,
 
   res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid, cpusetsize,
 			  cpuset);
+
+#ifdef RESET_VGETCPU_CACHE
+  if (!INTERNAL_SYSCALL_ERROR_P (res, err))
+    RESET_VGETCPU_CACHE ();
+#endif
+
   return (INTERNAL_SYSCALL_ERROR_P (res, err)
 	  ? INTERNAL_SYSCALL_ERRNO (res, err)
 	  : 0);
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
new file mode 100644
index 0000000000..640d3044fd
--- /dev/null
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/pthread_setaffinity.c
@@ -0,0 +1,14 @@
+#include <tls.h>
+
+#define RESET_VGETCPU_CACHE() \
+  do {			      \
+    asm volatile ("movl %0, %%fs:%P1\n\t"				      \
+		  "movl %0, %%fs:%P2"					      \
+		  :							      \
+		  : "ir" (0), "i" (offsetof (struct pthread,		      \
+					     header.vgetcpu_cache[0])),	      \
+		    "i" (offsetof (struct pthread,			      \
+				   header.vgetcpu_cache[1])));		\
+  } while (0)
+
+#include "../pthread_setaffinity.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
index c44d3f5e77..76a566b988 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_timedwait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -40,12 +40,6 @@
 	.align	16
 	cfi_startproc
 sem_timedwait:
-	/* First check for cancellation.  */
-	movl	%fs:CANCELHANDLING, %eax
-	andl	$0xfffffff9, %eax
-	cmpl	$8, %eax
-	je	11f
-
 	movl	(%rdi), %eax
 2:	testl	%eax, %eax
 	je	1f
@@ -160,16 +154,5 @@ sem_timedwait:
 
 	orl	$-1, %eax
 	jmp	10b
-	cfi_adjust_cfa_offset(-48)
-	cfi_restore(14)
-	cfi_restore(13)
-	cfi_restore(12)
-
-11:	/* Canceled.  */
-	movq	$0xffffffffffffffff, %fs:RESULT
-	LOCK
-	orl	$0x10, %fs:CANCELHANDLING
-	movq	%fs:CLEANUP_JMP_BUF, %rdi
-	jmp	HIDDEN_JUMPTARGET (__pthread_unwind)
 	cfi_endproc
 	.size	sem_timedwait,.-sem_timedwait
diff --git a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
index 63ecd063ab..5bd78eb944 100644
--- a/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
+++ b/nptl/sysdeps/unix/sysv/linux/x86_64/sem_wait.S
@@ -1,4 +1,4 @@
-/* Copyright (C) 2002, 2003, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2005, 2007 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
 
@@ -37,12 +37,6 @@
 	.align	16
 	cfi_startproc
 sem_wait:
-	/* First check for cancellation.  */
-	movl	%fs:CANCELHANDLING, %eax
-	andl	$0xfffffff9, %eax
-	cmpl	$8, %eax
-	je	4f
-
 	pushq	%r12
 	cfi_adjust_cfa_offset(8)
 	cfi_offset(12, -16)
@@ -109,12 +103,5 @@ sem_wait:
 	cfi_restore(12)
 
 	retq
-
-4:	/* Canceled.  */
-	movq	$0xffffffffffffffff, %fs:RESULT
-	LOCK
-	orl	$0x10, %fs:CANCELHANDLING
-	movq	%fs:CLEANUP_JMP_BUF, %rdi
-	jmp	HIDDEN_JUMPTARGET (__pthread_unwind)
 	cfi_endproc
 	.size	sem_wait,.-sem_wait
diff --git a/scripts/check-c++-types.sh b/scripts/check-c++-types.sh
index b207f12ba4..2864fe9aad 100755
--- a/scripts/check-c++-types.sh
+++ b/scripts/check-c++-types.sh
@@ -1,5 +1,5 @@
 #! /bin/bash
-# Copyright (C) 2003, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 2003, 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
@@ -32,7 +32,7 @@
 #
 data=$1
 shift
-cxx="$*"
+cxx=$(echo $* | sed 's/-fgnu89-inline//')
 while read t; do
   echo -n "$t:"
   $cxx -S -xc++ -o - -D_GNU_SOURCE <(cat <<EOF
diff --git a/sysdeps/unix/sysv/linux/Makefile b/sysdeps/unix/sysv/linux/Makefile
index 78553b9795..a063b33389 100644
--- a/sysdeps/unix/sysv/linux/Makefile
+++ b/sysdeps/unix/sysv/linux/Makefile
@@ -113,6 +113,8 @@ ifeq ($(subdir),posix)
 sysdep_headers += bits/initspin.h
 
 sysdep_routines += exit-thread sched_getcpu
+
+tests += tst-getcpu
 endif
 
 ifeq ($(subdir),inet)
diff --git a/sysdeps/unix/sysv/linux/sched_setaffinity.c b/sysdeps/unix/sysv/linux/sched_setaffinity.c
index ccd3c8f514..77cde47692 100644
--- a/sysdeps/unix/sysv/linux/sched_setaffinity.c
+++ b/sysdeps/unix/sysv/linux/sched_setaffinity.c
@@ -1,4 +1,5 @@
-/* Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
+/* Copyright (C) 2002, 2003, 2004, 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
@@ -67,7 +68,14 @@ __sched_setaffinity_new (pid_t pid, size_t cpusetsize, const cpu_set_t *cpuset)
 	return -1;
       }
 
-  return INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset);
+  int result = INLINE_SYSCALL (sched_setaffinity, 3, pid, cpusetsize, cpuset);
+
+#ifdef RESET_VGETCPU_CACHE
+  if (result != -1)
+    RESET_VGETCPU_CACHE ();
+#endif
+
+  return result;
 }
 versioned_symbol (libc, __sched_setaffinity_new, sched_setaffinity,
 		  GLIBC_2_3_4);
diff --git a/sysdeps/unix/sysv/linux/tst-getcpu.c b/sysdeps/unix/sysv/linux/tst-getcpu.c
new file mode 100644
index 0000000000..bf3cb57dd8
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/tst-getcpu.c
@@ -0,0 +1,54 @@
+#include <errno.h>
+#include <stdio.h>
+#include <sched.h>
+#include <unistd.h>
+
+
+static int
+do_test (void)
+{
+  cpu_set_t cs;
+  if (sched_getaffinity (getpid (), sizeof (cs), &cs) != 0)
+    {
+      printf ("getaffinity failed: %m\n");
+      return 1;
+    }
+
+  int result = 0;
+  int cpu = 0;
+  while (CPU_COUNT (&cs) != 0)
+    {
+      if (CPU_ISSET (cpu, &cs))
+	{
+	  cpu_set_t cs2;
+	  CPU_ZERO (&cs2);
+	  CPU_SET (cpu, &cs2);
+	  if (sched_setaffinity (getpid (), sizeof (cs2), &cs2) != 0)
+	    {
+	      printf ("setaffinity(%d) failed: %m\n", cpu);
+	      result = 1;
+	    }
+	  else
+	    {
+	      int cpu2 = sched_getcpu ();
+	      if (cpu2 == -1 && errno == ENOSYS)
+		{
+		  puts ("getcpu syscall not implemented");
+		  return 0;
+		}
+	      if (cpu2 != cpu)
+		{
+		  printf ("getcpu results %d not possible\n", cpu2);
+		  result = 1;
+		}
+	    }
+	  CPU_CLR (cpu, &cs);
+	}
+      ++cpu;
+    }
+
+  return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include <test-skeleton.c>
diff --git a/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c b/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c
new file mode 100644
index 0000000000..d1101c56f5
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/x86_64/sched_setaffinity.c
@@ -0,0 +1,14 @@
+#include <tls.h>
+
+#define RESET_VGETCPU_CACHE() \
+  do {			      \
+    asm volatile ("movl %0, %%fs:%P1\n\t"				      \
+		  "movl %0, %%fs:%P2"					      \
+		  :							      \
+		  : "ir" (0), "i" (offsetof (struct pthread,		      \
+					     header.vgetcpu_cache[0])),	      \
+		    "i" (offsetof (struct pthread,			      \
+				   header.vgetcpu_cache[1])));		\
+  } while (0)
+
+#include "../sched_setaffinity.c"
diff --git a/version.h b/version.h
index acd0ed11eb..d70070f2a3 100644
--- a/version.h
+++ b/version.h
@@ -1,4 +1,4 @@
 /* This file just defines the current version number of libc.  */
 
-#define RELEASE "development"
-#define VERSION "2.5.90"
+#define RELEASE "stable"
+#define VERSION "2.6"