summary refs log tree commit diff
path: root/malloc
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
committerUlrich Drepper <drepper@redhat.com>2004-12-22 20:10:10 +0000
commita334319f6530564d22e775935d9c91663623a1b4 (patch)
treeb5877475619e4c938e98757d518bb1e9cbead751 /malloc
parent0ecb606cb6cf65de1d9fc8a919bceb4be476c602 (diff)
downloadglibc-a334319f6530564d22e775935d9c91663623a1b4.tar.gz
glibc-a334319f6530564d22e775935d9c91663623a1b4.tar.xz
glibc-a334319f6530564d22e775935d9c91663623a1b4.zip
(CFLAGS-tst-align.c): Add -mpreferred-stack-boundary=4.
Diffstat (limited to 'malloc')
-rw-r--r--malloc/Makefile16
-rw-r--r--malloc/arena.c179
-rw-r--r--malloc/hooks.c49
-rw-r--r--malloc/malloc.c374
-rw-r--r--malloc/malloc.h142
-rw-r--r--malloc/mcheck.c30
-rw-r--r--malloc/memusage.c325
-rwxr-xr-xmalloc/memusage.sh28
-rw-r--r--malloc/memusagestat.c51
-rw-r--r--malloc/morecore.c54
-rw-r--r--malloc/mtrace.c20
-rw-r--r--malloc/mtrace.pl4
-rw-r--r--malloc/obstack.c71
-rw-r--r--malloc/obstack.h114
-rw-r--r--malloc/tst-malloc.c12
-rw-r--r--malloc/tst-mallocfork.c51
-rw-r--r--malloc/tst-mcheck.c91
-rwxr-xr-xmalloc/tst-mtrace.sh5
18 files changed, 507 insertions, 1109 deletions
diff --git a/malloc/Makefile b/malloc/Makefile
index c39eae5474..0512c49839 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -1,5 +1,4 @@
-# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006
-# Free Software Foundation, Inc.
+# Copyright (C) 1991-1999,2000,2001,2002,2003 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 
 # The GNU C Library is free software; you can redistribute it and/or
@@ -27,7 +26,7 @@ all:
 dist-headers := malloc.h
 headers := $(dist-headers) obstack.h mcheck.h
 tests := mallocbug tst-malloc tst-valloc tst-calloc tst-obstack \
-	 tst-mallocstate tst-mcheck tst-mallocfork
+	 tst-mallocstate
 test-srcs = tst-mtrace
 
 distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \
@@ -79,7 +78,6 @@ endif
 ifneq ($(cross-compiling),yes)
 # If the gd library is available we build the `memusagestat' program.
 ifneq ($(LIBGD),no)
-others: $(objpfx)memusage
 install-bin = memusagestat
 install-bin-script += memusage
 generated += memusagestat memusage
@@ -103,8 +101,6 @@ $(objpfx)memusagestat: $(memusagestat-modules:%=$(objpfx)%.o)
 
 include ../Rules
 
-CFLAGS-mcheck-init.c = $(PIC-ccflag)
-
 $(objpfx)libmcheck.a: $(objpfx)mcheck-init.o
 	-rm -f $@
 	$(patsubst %/,cd % &&,$(objpfx)) \
@@ -122,13 +118,9 @@ endif
 endif
 endif
 
-tst-mcheck-ENV = MALLOC_CHECK_=3
-
 # Uncomment this for test releases.  For public releases it is too expensive.
 #CPPFLAGS-malloc.o += -DMALLOC_DEBUG=1
 
-sLIBdir := $(shell echo $(slibdir) | sed 's,lib\(\|64\)$$,\\\\$$LIB,')
-
 $(objpfx)mtrace: mtrace.pl
 	rm -f $@.new
 	sed -e 's|@PERL@|$(PERL)|' -e 's|@XXX@|$(address-width)|' \
@@ -138,12 +130,12 @@ $(objpfx)mtrace: mtrace.pl
 $(objpfx)memusage: memusage.sh
 	rm -f $@.new
 	sed -e 's|@BASH@|$(BASH)|' -e 's|@VERSION@|$(version)|' \
-	    -e 's|@SLIBDIR@|$(sLIBdir)|' -e 's|@BINDIR@|$(bindir)|' $^ > $@.new \
+	    -e 's|@SLIBDIR@|$(slibdir)|' -e 's|@BINDIR@|$(bindir)|' $^ > $@.new \
 	&& rm -f $@ && mv $@.new $@ && chmod +x $@
 
 
 # The implementation uses `dlsym'
-$(objpfx)libmemusage.so: $(common-objpfx)dlfcn/libdl.so $(elfobjdir)/ld.so
+$(objpfx)libmemusage.so: $(common-objpfx)dlfcn/libdl.so
 
 # Extra dependencies
 $(foreach o,$(all-object-suffixes),$(objpfx)malloc$(o)): arena.c hooks.c
diff --git a/malloc/arena.c b/malloc/arena.c
index 0dcb7cb9f8..026f2c7822 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -1,6 +1,5 @@
 /* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 2001,2002,2003,2004,2005,2006,2007
-   Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
 
@@ -19,17 +18,13 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
-#include <stdbool.h>
+/* $Id$ */
 
 /* Compile-time constants.  */
 
 #define HEAP_MIN_SIZE (32*1024)
 #ifndef HEAP_MAX_SIZE
-# ifdef DEFAULT_MMAP_THRESHOLD_MAX
-#  define HEAP_MAX_SIZE (2 * DEFAULT_MMAP_THRESHOLD_MAX)
-# else
-#  define HEAP_MAX_SIZE (1024*1024) /* must be a power of two */
-# endif
+#define HEAP_MAX_SIZE (1024*1024) /* must be a power of two */
 #endif
 
 /* HEAP_MIN_SIZE and HEAP_MAX_SIZE limit the size of mmap()ed heaps
@@ -60,20 +55,9 @@ typedef struct _heap_info {
   mstate ar_ptr; /* Arena for this heap. */
   struct _heap_info *prev; /* Previous heap. */
   size_t size;   /* Current size in bytes. */
-  size_t mprotect_size;	/* Size in bytes that has been mprotected
-			   PROT_READ|PROT_WRITE.  */
-  /* Make sure the following data is properly aligned, particularly
-     that sizeof (heap_info) + 2 * SIZE_SZ is a multiple of
-     MALLOC_ALIGNMENT. */
-  char pad[-6 * SIZE_SZ & MALLOC_ALIGN_MASK];
+  size_t pad;    /* Make sure the following data is properly aligned. */
 } heap_info;
 
-/* Get a compile-time error if the heap_info padding is not correct
-   to make alignment work as expected in sYSMALLOc.  */
-extern int sanity_check_heap_info_alignment[(sizeof (heap_info)
-					     + 2 * SIZE_SZ) % MALLOC_ALIGNMENT
-					    ? -1 : 1];
-
 /* Thread specific data */
 
 static tsd_key_t arena_key;
@@ -224,10 +208,6 @@ free_atfork(Void_t* mem, const Void_t *caller)
     (void)mutex_unlock(&ar_ptr->mutex);
 }
 
-
-/* Counter for number of times the list is locked by the same thread.  */
-static unsigned int atfork_recursive_cntr;
-
 /* The following two functions are registered via thread_atfork() to
    make sure that the mutexes remain in a consistent state in the
    fork()ed version of a thread.  Also adapt the malloc and free hooks
@@ -241,18 +221,7 @@ ptmalloc_lock_all (void)
 
   if(__malloc_initialized < 1)
     return;
-  if (mutex_trylock(&list_lock))
-    {
-      Void_t *my_arena;
-      tsd_getspecific(arena_key, my_arena);
-      if (my_arena == ATFORK_ARENA_PTR)
-	/* This is the same thread which already locks the global list.
-	   Just bump the counter.  */
-	goto out;
-
-      /* This thread has to wait its turn.  */
-      (void)mutex_lock(&list_lock);
-    }
+  (void)mutex_lock(&list_lock);
   for(ar_ptr = &main_arena;;) {
     (void)mutex_lock(&ar_ptr->mutex);
     ar_ptr = ar_ptr->next;
@@ -265,8 +234,6 @@ ptmalloc_lock_all (void)
   /* Only the current thread may perform malloc/free calls now. */
   tsd_getspecific(arena_key, save_arena);
   tsd_setspecific(arena_key, ATFORK_ARENA_PTR);
- out:
-  ++atfork_recursive_cntr;
 }
 
 static void
@@ -276,8 +243,6 @@ ptmalloc_unlock_all (void)
 
   if(__malloc_initialized < 1)
     return;
-  if (--atfork_recursive_cntr != 0)
-    return;
   tsd_setspecific(arena_key, save_arena);
   __malloc_hook = save_malloc_hook;
   __free_hook = save_free_hook;
@@ -291,7 +256,7 @@ ptmalloc_unlock_all (void)
 
 #ifdef __linux__
 
-/* In NPTL, unlocking a mutex in the child process after a
+/* In LinuxThreads, unlocking a mutex in the child process after a
    fork() is currently unsafe, whereas re-initializing it is safe and
    does not leak resources.  Therefore, a special atfork handler is
    installed for the child. */
@@ -314,7 +279,6 @@ ptmalloc_unlock_all2 (void)
     if(ar_ptr == &main_arena) break;
   }
   mutex_init(&list_lock);
-  atfork_recursive_cntr = 0;
 }
 
 #else
@@ -389,6 +353,8 @@ libc_hidden_proto (_dl_open_hook);
 # endif
 
 # if defined SHARED && defined USE_TLS && !USE___THREAD
+# include <stdbool.h>
+
 /* This is called by __pthread_initialize_minimal when it needs to use
    malloc to set up the TLS state.  We cannot do the full work of
    ptmalloc_init (below) until __pthread_initialize_minimal has finished,
@@ -516,13 +482,8 @@ ptmalloc_init (void)
 		s = &envline[7];
 	      break;
 	    case 8:
-	      if (! secure)
-		{
-		  if (memcmp (envline, "TOP_PAD_", 8) == 0)
-		    mALLOPt(M_TOP_PAD, atoi(&envline[9]));
-		  else if (memcmp (envline, "PERTURB_", 8) == 0)
-		    mALLOPt(M_PERTURB, atoi(&envline[9]));
-		}
+	      if (! secure && memcmp (envline, "TOP_PAD_", 8) == 0)
+		mALLOPt(M_TOP_PAD, atoi(&envline[9]));
 	      break;
 	    case 9:
 	      if (! secure && memcmp (envline, "MMAP_MAX_", 9) == 0)
@@ -549,8 +510,6 @@ ptmalloc_init (void)
 	mALLOPt(M_TRIM_THRESHOLD, atoi(s));
       if((s = getenv("MALLOC_TOP_PAD_")))
 	mALLOPt(M_TOP_PAD, atoi(s));
-      if((s = getenv("MALLOC_PERTURB_")))
-	mALLOPt(M_PERTURB, atoi(s));
       if((s = getenv("MALLOC_MMAP_THRESHOLD_")))
 	mALLOPt(M_MMAP_THRESHOLD, atoi(s));
       if((s = getenv("MALLOC_MMAP_MAX_")))
@@ -558,8 +517,8 @@ ptmalloc_init (void)
     }
   s = getenv("MALLOC_CHECK_");
 #endif
-  if(s && s[0]) {
-    mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0'));
+  if(s) {
+    if(s[0]) mALLOPt(M_CHECK_ACTION, (int)(s[0] - '0'));
     if (check_action != 0)
       __malloc_check_init();
   }
@@ -695,7 +654,6 @@ new_heap(size, top_pad) size_t size, top_pad;
   }
   h = (heap_info *)p2;
   h->size = size;
-  h->mprotect_size = size;
   THREAD_STAT(stat_n_heaps++);
   return h;
 }
@@ -716,36 +674,19 @@ grow_heap(h, diff) heap_info *h; long diff;
   if(diff >= 0) {
     diff = (diff + page_mask) & ~page_mask;
     new_size = (long)h->size + diff;
-    if((unsigned long) new_size > (unsigned long) HEAP_MAX_SIZE)
+    if(new_size > HEAP_MAX_SIZE)
       return -1;
-    if((unsigned long) new_size > h->mprotect_size) {
-      if (mprotect((char *)h + h->mprotect_size,
-		   (unsigned long) new_size - h->mprotect_size,
-		   PROT_READ|PROT_WRITE) != 0)
-	return -2;
-      h->mprotect_size = new_size;
-    }
+    if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0)
+      return -2;
   } else {
     new_size = (long)h->size + diff;
     if(new_size < (long)sizeof(*h))
       return -1;
     /* Try to re-map the extra heap space freshly to save memory, and
        make it inaccessible. */
-#ifdef _LIBC
-    if (__builtin_expect (__libc_enable_secure, 0))
-#else
-    if (1)
-#endif
-      {
-	if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE,
-			MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
-	  return -2;
-	h->mprotect_size = new_size;
-      }
-#ifdef _LIBC
-    else
-      madvise ((char *)h + new_size, -diff, MADV_DONTNEED);
-#endif
+    if((char *)MMAP((char *)h + new_size, -diff, PROT_NONE,
+                    MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
+      return -2;
     /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/
   }
   h->size = new_size;
@@ -818,48 +759,6 @@ heap_trim(heap, pad) heap_info *heap; size_t pad;
   return 1;
 }
 
-/* Create a new arena with initial size "size".  */
-
-static mstate
-_int_new_arena(size_t size)
-{
-  mstate a;
-  heap_info *h;
-  char *ptr;
-  unsigned long misalign;
-
-  h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT),
-	       mp_.top_pad);
-  if(!h) {
-    /* Maybe size is too large to fit in a single heap.  So, just try
-       to create a minimally-sized arena and let _int_malloc() attempt
-       to deal with the large request via mmap_chunk().  */
-    h = new_heap(sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT, mp_.top_pad);
-    if(!h)
-      return 0;
-  }
-  a = h->ar_ptr = (mstate)(h+1);
-  malloc_init_state(a);
-  /*a->next = NULL;*/
-  a->system_mem = a->max_system_mem = h->size;
-  arena_mem += h->size;
-#ifdef NO_THREADS
-  if((unsigned long)(mp_.mmapped_mem + arena_mem + main_arena.system_mem) >
-     mp_.max_total_mem)
-    mp_.max_total_mem = mp_.mmapped_mem + arena_mem + main_arena.system_mem;
-#endif
-
-  /* Set up the top chunk, with proper alignment. */
-  ptr = (char *)(a + 1);
-  misalign = (unsigned long)chunk2mem(ptr) & MALLOC_ALIGN_MASK;
-  if (misalign > 0)
-    ptr += MALLOC_ALIGNMENT - misalign;
-  top(a) = (mchunkptr)ptr;
-  set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
-
-  return a;
-}
-
 static mstate
 internal_function
 #if __STD_C
@@ -930,6 +829,48 @@ arena_get2(a_tsd, size) mstate a_tsd; size_t size;
   return a;
 }
 
+/* Create a new arena with initial size "size".  */
+
+mstate
+_int_new_arena(size_t size)
+{
+  mstate a;
+  heap_info *h;
+  char *ptr;
+  unsigned long misalign;
+
+  h = new_heap(size + (sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT),
+	       mp_.top_pad);
+  if(!h) {
+    /* Maybe size is too large to fit in a single heap.  So, just try
+       to create a minimally-sized arena and let _int_malloc() attempt
+       to deal with the large request via mmap_chunk().  */
+    h = new_heap(sizeof(*h) + sizeof(*a) + MALLOC_ALIGNMENT, mp_.top_pad);
+    if(!h)
+      return 0;
+  }
+  a = h->ar_ptr = (mstate)(h+1);
+  malloc_init_state(a);
+  /*a->next = NULL;*/
+  a->system_mem = a->max_system_mem = h->size;
+  arena_mem += h->size;
+#ifdef NO_THREADS
+  if((unsigned long)(mp_.mmapped_mem + arena_mem + main_arena.system_mem) >
+     mp_.max_total_mem)
+    mp_.max_total_mem = mp_.mmapped_mem + arena_mem + main_arena.system_mem;
+#endif
+
+  /* Set up the top chunk, with proper alignment. */
+  ptr = (char *)(a + 1);
+  misalign = (unsigned long)chunk2mem(ptr) & MALLOC_ALIGN_MASK;
+  if (misalign > 0)
+    ptr += MALLOC_ALIGNMENT - misalign;
+  top(a) = (mchunkptr)ptr;
+  set_head(top(a), (((char*)h + h->size) - ptr) | PREV_INUSE);
+
+  return a;
+}
+
 #endif /* USE_ARENAS */
 
 /*
diff --git a/malloc/hooks.c b/malloc/hooks.c
index 708f0faf83..a5c97f3133 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 Free Software Foundation, Inc.
+   Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>, 2001.
 
@@ -18,6 +18,8 @@
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 
+/* $Id$ */
+
 /* What to do if the standard debugging hooks are in place and a
    corrupt pointer is detected: do nothing (0), print an error message
    (1), or call abort() (2). */
@@ -144,9 +146,9 @@ mem2mem_check(ptr, sz) Void_t *ptr; size_t sz;
 static mchunkptr
 internal_function
 #if __STD_C
-mem2chunk_check(Void_t* mem, unsigned char **magic_p)
+mem2chunk_check(Void_t* mem)
 #else
-mem2chunk_check(mem, magic_p) Void_t* mem; unsigned char **magic_p;
+mem2chunk_check(mem) Void_t* mem;
 #endif
 {
   mchunkptr p;
@@ -171,6 +173,7 @@ mem2chunk_check(mem, magic_p) Void_t* mem; unsigned char **magic_p;
     for(sz += SIZE_SZ-1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
       if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
     }
+    ((unsigned char*)p)[sz] ^= 0xFF;
   } else {
     unsigned long offset, page_mask = malloc_getpagesize-1;
 
@@ -190,10 +193,8 @@ mem2chunk_check(mem, magic_p) Void_t* mem; unsigned char **magic_p;
     for(sz -= 1; (c = ((unsigned char*)p)[sz]) != magic; sz -= c) {
       if(c<=0 || sz<(c+2*SIZE_SZ)) return NULL;
     }
+    ((unsigned char*)p)[sz] ^= 0xFF;
   }
-  ((unsigned char*)p)[sz] ^= 0xFF;
-  if (magic_p)
-    *magic_p = (unsigned char *)p + sz;
   return p;
 }
 
@@ -231,11 +232,7 @@ top_check()
   sbrk_size = front_misalign + mp_.top_pad + MINSIZE;
   sbrk_size += pagesz - ((unsigned long)(brk + sbrk_size) & (pagesz - 1));
   new_brk = (char*)(MORECORE (sbrk_size));
-  if (new_brk == (char*)(MORECORE_FAILURE))
-    {
-      MALLOC_FAILURE_ACTION;
-      return -1;
-    }
+  if (new_brk == (char*)(MORECORE_FAILURE)) return -1;
   /* Call the `morecore' hook if necessary.  */
   if (__after_morecore_hook)
     (*__after_morecore_hook) ();
@@ -256,11 +253,6 @@ malloc_check(sz, caller) size_t sz; const Void_t *caller;
 {
   Void_t *victim;
 
-  if (sz+1 == 0) {
-    MALLOC_FAILURE_ACTION;
-    return NULL;
-  }
-
   (void)mutex_lock(&main_arena.mutex);
   victim = (top_check() >= 0) ? _int_malloc(&main_arena, sz+1) : NULL;
   (void)mutex_unlock(&main_arena.mutex);
@@ -278,7 +270,7 @@ free_check(mem, caller) Void_t* mem; const Void_t *caller;
 
   if(!mem) return;
   (void)mutex_lock(&main_arena.mutex);
-  p = mem2chunk_check(mem, NULL);
+  p = mem2chunk_check(mem);
   if(!p) {
     (void)mutex_unlock(&main_arena.mutex);
 
@@ -310,19 +302,10 @@ realloc_check(oldmem, bytes, caller)
   mchunkptr oldp;
   INTERNAL_SIZE_T nb, oldsize;
   Void_t* newmem = 0;
-  unsigned char *magic_p;
 
-  if (bytes+1 == 0) {
-    MALLOC_FAILURE_ACTION;
-    return NULL;
-  }
   if (oldmem == 0) return malloc_check(bytes, NULL);
-  if (bytes == 0) {
-    free_check (oldmem, NULL);
-    return NULL;
-  }
   (void)mutex_lock(&main_arena.mutex);
-  oldp = mem2chunk_check(oldmem, &magic_p);
+  oldp = mem2chunk_check(oldmem);
   (void)mutex_unlock(&main_arena.mutex);
   if(!oldp) {
     malloc_printerr(check_action, "realloc(): invalid pointer", oldmem);
@@ -374,12 +357,6 @@ realloc_check(oldmem, bytes, caller)
 #if HAVE_MMAP
   }
 #endif
-
-  /* mem2chunk_check changed the magic byte in the old chunk.
-     If newmem is NULL, then the old chunk will still be used though,
-     so we need to invert that change here.  */
-  if (newmem == NULL) *magic_p ^= 0xFF;
-
   (void)mutex_unlock(&main_arena.mutex);
 
   return mem2mem_check(newmem, bytes);
@@ -399,10 +376,6 @@ memalign_check(alignment, bytes, caller)
   if (alignment <= MALLOC_ALIGNMENT) return malloc_check(bytes, NULL);
   if (alignment <  MINSIZE) alignment = MINSIZE;
 
-  if (bytes+1 == 0) {
-    MALLOC_FAILURE_ACTION;
-    return NULL;
-  }
   checked_request2size(bytes+1, nb);
   (void)mutex_lock(&main_arena.mutex);
   mem = (top_check() >= 0) ? _int_memalign(&main_arena, alignment, bytes+1) :
@@ -582,7 +555,7 @@ public_sET_STATe(Void_t* msptr)
   (void)mutex_lock(&main_arena.mutex);
   /* There are no fastchunks.  */
   clear_fastchunks(&main_arena);
-  set_max_fast(DEFAULT_MXFAST);
+  set_max_fast(&main_arena, DEFAULT_MXFAST);
   for (i=0; i<NFASTBINS; ++i)
     main_arena.fastbins[i] = 0;
   for (i=0; i<BINMAPSIZE; ++i)
diff --git a/malloc/malloc.c b/malloc/malloc.c
index a369001520..e3ccbde7b5 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -1,5 +1,5 @@
-/* Malloc implementation for multiple threads without lock contention.
-   Copyright (C) 1996-2002,2003,2004,2005,2006 Free Software Foundation, Inc.
+  /* Malloc implementation for multiple threads without lock contention.
+   Copyright (C) 1996-2002, 2003, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Wolfram Gloger <wg@malloc.de>
    and Doug Lea <dl@cs.oswego.edu>, 2001.
@@ -24,6 +24,7 @@
   Doug Lea and adapted to multiple threads/arenas by Wolfram Gloger.
 
 * Version ptmalloc2-20011215
+  $Id$
   based on:
   VERSION 2.7.0 Sun Mar 11 14:14:06 2001  Doug Lea  (dl at gee)
 
@@ -188,8 +189,7 @@
     Changing default word sizes:
 
     INTERNAL_SIZE_T            size_t
-    MALLOC_ALIGNMENT           MAX (2 * sizeof(INTERNAL_SIZE_T),
-				    __alignof__ (long double))
+    MALLOC_ALIGNMENT           2 * sizeof(INTERNAL_SIZE_T)
 
     Configuration and functionality options:
 
@@ -259,7 +259,6 @@
 
 #ifdef _LIBC
 #include <stdio-common/_itoa.h>
-#include <bits/wordsize.h>
 #endif
 
 #ifdef __cplusplus
@@ -382,15 +381,6 @@ extern "C" {
 
 
 #ifndef MALLOC_ALIGNMENT
-/* XXX This is the correct definition.  It differs from 2*SIZE_SZ only on
-   powerpc32.  For the time being, changing this is causing more
-   compatibility problems due to malloc_get_state/malloc_set_state than
-   will returning blocks not adequately aligned for long double objects
-   under -mlong-double-128.
-
-#define MALLOC_ALIGNMENT       (2 * SIZE_SZ < __alignof__ (long double) \
-				? __alignof__ (long double) : 2 * SIZE_SZ)
-*/
 #define MALLOC_ALIGNMENT       (2 * SIZE_SZ)
 #endif
 
@@ -1016,7 +1006,6 @@ struct mallinfo public_mALLINFo(void);
 struct mallinfo public_mALLINFo();
 #endif
 
-#ifndef _LIBC
 /*
   independent_calloc(size_t n_elements, size_t element_size, Void_t* chunks[]);
 
@@ -1140,8 +1129,6 @@ Void_t** public_iCOMALLOc(size_t, size_t*, Void_t**);
 Void_t** public_iCOMALLOc();
 #endif
 
-#endif /* _LIBC */
-
 
 /*
   pvalloc(size_t n);
@@ -1416,27 +1403,6 @@ int      __posix_memalign(void **, size_t, size_t);
 #endif
 
 /*
-  MMAP_THRESHOLD_MAX and _MIN are the bounds on the dynamically
-  adjusted MMAP_THRESHOLD.
-*/
-
-#ifndef DEFAULT_MMAP_THRESHOLD_MIN
-#define DEFAULT_MMAP_THRESHOLD_MIN (128 * 1024)
-#endif
-
-#ifndef DEFAULT_MMAP_THRESHOLD_MAX
-  /* For 32-bit platforms we cannot increase the maximum mmap
-     threshold much because it is also the minimum value for the
-     maximum heap size and its alignment.  Going above 512k (i.e., 1M
-     for new heaps) wastes too much address space.  */
-# if __WORDSIZE == 32
-#  define DEFAULT_MMAP_THRESHOLD_MAX (512 * 1024)
-# else
-#  define DEFAULT_MMAP_THRESHOLD_MAX (4 * 1024 * 1024 * sizeof(long))
-# endif
-#endif
-
-/*
   M_MMAP_THRESHOLD is the request size threshold for using mmap()
   to service a request. Requests of at least this size that cannot
   be allocated using already-existing space will be serviced via mmap.
@@ -1475,63 +1441,12 @@ int      __posix_memalign(void **, size_t, size_t);
   "large" chunks, but the value of "large" varies across systems.  The
   default is an empirically derived value that works well in most
   systems.
-
-
-  Update in 2006:
-  The above was written in 2001. Since then the world has changed a lot.
-  Memory got bigger. Applications got bigger. The virtual address space
-  layout in 32 bit linux changed.
-
-  In the new situation, brk() and mmap space is shared and there are no
-  artificial limits on brk size imposed by the kernel. What is more,
-  applications have started using transient allocations larger than the
-  128Kb as was imagined in 2001.
-
-  The price for mmap is also high now; each time glibc mmaps from the
-  kernel, the kernel is forced to zero out the memory it gives to the
-  application. Zeroing memory is expensive and eats a lot of cache and
-  memory bandwidth. This has nothing to do with the efficiency of the
-  virtual memory system, by doing mmap the kernel just has no choice but
-  to zero.
-
-  In 2001, the kernel had a maximum size for brk() which was about 800
-  megabytes on 32 bit x86, at that point brk() would hit the first
-  mmaped shared libaries and couldn't expand anymore. With current 2.6
-  kernels, the VA space layout is different and brk() and mmap
-  both can span the entire heap at will.
-
-  Rather than using a static threshold for the brk/mmap tradeoff,
-  we are now using a simple dynamic one. The goal is still to avoid
-  fragmentation. The old goals we kept are
-  1) try to get the long lived large allocations to use mmap()
-  2) really large allocations should always use mmap()
-  and we're adding now:
-  3) transient allocations should use brk() to avoid forcing the kernel
-     having to zero memory over and over again
-
-  The implementation works with a sliding threshold, which is by default
-  limited to go between 128Kb and 32Mb (64Mb for 64 bitmachines) and starts
-  out at 128Kb as per the 2001 default.
-
-  This allows us to satisfy requirement 1) under the assumption that long
-  lived allocations are made early in the process' lifespan, before it has
-  started doing dynamic allocations of the same size (which will
-  increase the threshold).
-
-  The upperbound on the threshold satisfies requirement 2)
-
-  The threshold goes up in value when the application frees memory that was
-  allocated with the mmap allocator. The idea is that once the application
-  starts freeing memory of a certain size, it's highly probable that this is
-  a size the application uses for transient allocations. This estimator
-  is there to satisfy the new third requirement.
-
 */
 
 #define M_MMAP_THRESHOLD      -3
 
 #ifndef DEFAULT_MMAP_THRESHOLD
-#define DEFAULT_MMAP_THRESHOLD DEFAULT_MMAP_THRESHOLD_MIN
+#define DEFAULT_MMAP_THRESHOLD (128 * 1024)
 #endif
 
 /*
@@ -1592,10 +1507,8 @@ Void_t*         _int_memalign(mstate, size_t, size_t);
 Void_t*         _int_valloc(mstate, size_t);
 static Void_t*  _int_pvalloc(mstate, size_t);
 /*static Void_t*  cALLOc(size_t, size_t);*/
-#ifndef _LIBC
 static Void_t** _int_icalloc(mstate, size_t, size_t, Void_t**);
 static Void_t** _int_icomalloc(mstate, size_t, size_t*, Void_t**);
-#endif
 static int      mTRIm(size_t);
 static size_t   mUSABLe(Void_t*);
 static void     mSTATs(void);
@@ -1808,7 +1721,7 @@ struct malloc_chunk {
       mem-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |             User data starts here...                          .
             .                                                               .
-            .             (malloc_usable_size() bytes)                      .
+            .             (malloc_usable_space() bytes)                     .
             .                                                               |
 nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
             |             Size of chunk                                     |
@@ -1890,11 +1803,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 
 /* Check if m has acceptable alignment */
 
-#define aligned_OK(m)  (((unsigned long)(m) & MALLOC_ALIGN_MASK) == 0)
-
-#define misaligned_chunk(p) \
-  ((uintptr_t)(MALLOC_ALIGNMENT == 2 * SIZE_SZ ? (p) : chunk2mem (p)) \
-   & MALLOC_ALIGN_MASK)
+#define aligned_OK(m)  (((unsigned long)((m)) & (MALLOC_ALIGN_MASK)) == 0)
 
 
 /*
@@ -2061,9 +1970,7 @@ nextchunk-> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 typedef struct malloc_chunk* mbinptr;
 
 /* addressing -- note that bin_at(0) does not exist */
-#define bin_at(m, i) \
-  (mbinptr) (((char *) &((m)->bins[((i) - 1) * 2]))			      \
-	     - offsetof (struct malloc_chunk, fd))
+#define bin_at(m, i) ((mbinptr)((char*)&((m)->bins[(i)<<1]) - (SIZE_SZ<<1)))
 
 /* analog of ++bin */
 #define next_bin(b)  ((mbinptr)((char*)(b) + (sizeof(mchunkptr)<<1)))
@@ -2245,9 +2152,9 @@ typedef struct malloc_chunk* mfastbinptr;
 
 #define FASTCHUNKS_BIT        (1U)
 
-#define have_fastchunks(M)     (((M)->flags &  FASTCHUNKS_BIT) == 0)
-#define clear_fastchunks(M)    ((M)->flags |=  FASTCHUNKS_BIT)
-#define set_fastchunks(M)      ((M)->flags &= ~FASTCHUNKS_BIT)
+#define have_fastchunks(M)     (((M)->max_fast &  FASTCHUNKS_BIT) == 0)
+#define clear_fastchunks(M)    ((M)->max_fast |=  FASTCHUNKS_BIT)
+#define set_fastchunks(M)      ((M)->max_fast &= ~FASTCHUNKS_BIT)
 
 /*
   NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
@@ -2260,10 +2167,10 @@ typedef struct malloc_chunk* mfastbinptr;
 
 #define NONCONTIGUOUS_BIT     (2U)
 
-#define contiguous(M)          (((M)->flags &  NONCONTIGUOUS_BIT) == 0)
-#define noncontiguous(M)       (((M)->flags &  NONCONTIGUOUS_BIT) != 0)
-#define set_noncontiguous(M)   ((M)->flags |=  NONCONTIGUOUS_BIT)
-#define set_contiguous(M)      ((M)->flags &= ~NONCONTIGUOUS_BIT)
+#define contiguous(M)          (((M)->max_fast &  NONCONTIGUOUS_BIT) == 0)
+#define noncontiguous(M)       (((M)->max_fast &  NONCONTIGUOUS_BIT) != 0)
+#define set_noncontiguous(M)   ((M)->max_fast |=  NONCONTIGUOUS_BIT)
+#define set_contiguous(M)      ((M)->max_fast &= ~NONCONTIGUOUS_BIT)
 
 /*
    Set value of max_fast.
@@ -2272,9 +2179,10 @@ typedef struct malloc_chunk* mfastbinptr;
    Setting the value clears fastchunk bit but preserves noncontiguous bit.
 */
 
-#define set_max_fast(s) \
-  global_max_fast = ((s) == 0)? SMALLBIN_WIDTH: request2size(s)
-#define get_max_fast() global_max_fast
+#define set_max_fast(M, s) \
+  (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
+  FASTCHUNKS_BIT | \
+  ((M)->max_fast &  NONCONTIGUOUS_BIT)
 
 
 /*
@@ -2284,15 +2192,16 @@ typedef struct malloc_chunk* mfastbinptr;
 struct malloc_state {
   /* Serialize access.  */
   mutex_t mutex;
-
-  /* Flags (formerly in max_fast).  */
-  int flags;
+  // Should we have padding to move the mutex to its own cache line?
 
 #if THREAD_STATS
   /* Statistics for locking.  Only used if THREAD_STATS is defined.  */
   long stat_lock_direct, stat_lock_loop, stat_lock_wait;
 #endif
 
+  /* The maximum chunk size to be eligible for fastbin */
+  INTERNAL_SIZE_T  max_fast;   /* low 2 bits used as flags */
+
   /* Fastbins */
   mfastbinptr      fastbins[NFASTBINS];
 
@@ -2303,7 +2212,7 @@ struct malloc_state {
   mchunkptr        last_remainder;
 
   /* Normal bins packed as described above */
-  mchunkptr        bins[NBINS * 2 - 2];
+  mchunkptr        bins[NBINS * 2];
 
   /* Bitmap of bins */
   unsigned int     binmap[BINMAPSIZE];
@@ -2326,10 +2235,6 @@ struct malloc_par {
   int              n_mmaps;
   int              n_mmaps_max;
   int              max_n_mmaps;
-  /* the mmap_threshold is dynamic, until the user sets
-     it manually, at which point we need to disable any
-     dynamic behavior. */
-  int              no_dyn_threshold;
 
   /* Cache malloc_getpagesize */
   unsigned int     pagesize;
@@ -2357,10 +2262,6 @@ static struct malloc_state main_arena;
 
 static struct malloc_par mp_;
 
-
-/* Maximum size of memory handled in fastbins.  */
-static INTERNAL_SIZE_T global_max_fast;
-
 /*
   Initialize a malloc_state struct.
 
@@ -2390,9 +2291,8 @@ static void malloc_init_state(av) mstate av;
   if (av != &main_arena)
 #endif
     set_noncontiguous(av);
-  if (av == &main_arena)
-    set_max_fast(DEFAULT_MXFAST);
-  av->flags |= FASTCHUNKS_BIT;
+
+  set_max_fast(av, DEFAULT_MXFAST);
 
   av->top            = initial_top(av);
 }
@@ -2405,9 +2305,7 @@ static void malloc_init_state(av) mstate av;
 static Void_t*  sYSMALLOc(INTERNAL_SIZE_T, mstate);
 static int      sYSTRIm(size_t, mstate);
 static void     malloc_consolidate(mstate);
-#ifndef _LIBC
 static Void_t** iALLOc(mstate, size_t, size_t*, int, Void_t**);
-#endif
 #else
 static Void_t*  sYSMALLOc();
 static int      sYSTRIm();
@@ -2461,14 +2359,6 @@ void weak_variable (*__after_morecore_hook) (void) = NULL;
 static int check_action = DEFAULT_CHECK_ACTION;
 
 
-/* ------------------ Testing support ----------------------------------*/
-
-static int perturb_byte;
-
-#define alloc_perturb(p, n) memset (p, (perturb_byte ^ 0xff) & 0xff, n)
-#define free_perturb(p, n) memset (p, perturb_byte & 0xff, n)
-
-
 /* ------------------- Support for multiple arenas -------------------- */
 #include "arena.c"
 
@@ -2734,9 +2624,9 @@ static void do_check_malloc_state(mstate av)
   /* properties of fastbins */
 
   /* max_fast is in allowed range */
-  assert((get_max_fast () & ~1) <= request2size(MAX_FAST_SIZE));
+  assert((av->max_fast & ~1) <= request2size(MAX_FAST_SIZE));
 
-  max_fast_bin = fastbin_index(get_max_fast ());
+  max_fast_bin = fastbin_index(av->max_fast);
 
   for (i = 0; i < NFASTBINS; ++i) {
     p = av->fastbins[i];
@@ -2862,7 +2752,6 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
   unsigned long   sum;            /* for updating stats */
 
   size_t          pagemask  = mp_.pagesize - 1;
-  bool            tried_mmap = false;
 
 
 #if HAVE_MMAP
@@ -2879,14 +2768,12 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
 
     char* mm;             /* return value from mmap call*/
 
-  try_mmap:
     /*
       Round up size to nearest page.  For mmapped chunks, the overhead
       is one SIZE_SZ unit larger than for normal chunks, because there
       is no following chunk whose prev_size field could be used.
     */
     size = (nb + SIZE_SZ + MALLOC_ALIGN_MASK + pagemask) & ~pagemask;
-    tried_mmap = true;
 
     /* Don't try if size wraps around 0 */
     if ((unsigned long)(size) > (unsigned long)(nb)) {
@@ -2970,8 +2857,7 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
     /* First try to extend the current heap. */
     old_heap = heap_for_ptr(old_top);
     old_heap_size = old_heap->size;
-    if ((long) (MINSIZE + nb - old_size) > 0
-	&& grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {
+    if (grow_heap(old_heap, MINSIZE + nb - old_size) == 0) {
       av->system_mem += old_heap->size - old_heap_size;
       arena_mem += old_heap->size - old_heap_size;
 #if 0
@@ -3011,9 +2897,6 @@ static Void_t* sYSMALLOc(nb, av) INTERNAL_SIZE_T nb; mstate av;
 	set_foot(old_top, (old_size + 2*SIZE_SZ));
       }
     }
-    else if (!tried_mmap)
-      /* We can at least try to use to mmap memory.  */
-      goto try_mmap;
 
   } else { /* av == main_arena */
 
@@ -3367,31 +3250,19 @@ munmap_chunk(p) mchunkptr p;
 #endif
 {
   INTERNAL_SIZE_T size = chunksize(p);
+  int ret;
 
   assert (chunk_is_mmapped(p));
 #if 0
   assert(! ((char*)p >= mp_.sbrk_base && (char*)p < mp_.sbrk_base + mp_.sbrked_mem));
   assert((mp_.n_mmaps > 0));
 #endif
-
-  uintptr_t block = (uintptr_t) p - p->prev_size;
-  size_t total_size = p->prev_size + size;
-  /* Unfortunately we have to do the compilers job by hand here.  Normally
-     we would test BLOCK and TOTAL-SIZE separately for compliance with the
-     page size.  But gcc does not recognize the optimization possibility
-     (in the moment at least) so we combine the two values into one before
-     the bit test.  */
-  if (__builtin_expect (((block | total_size) & (mp_.pagesize - 1)) != 0, 0))
-    {
-      malloc_printerr (check_action, "munmap_chunk(): invalid pointer",
-		       chunk2mem (p));
-      return;
-    }
+  assert(((p->prev_size + size) & (mp_.pagesize-1)) == 0);
 
   mp_.n_mmaps--;
-  mp_.mmapped_mem -= total_size;
+  mp_.mmapped_mem -= (size + p->prev_size);
 
-  int ret __attribute__ ((unused)) = munmap((char *)block, total_size);
+  ret = munmap((char *)p - p->prev_size, size + p->prev_size);
 
   /* munmap returns non-zero on failure */
   assert(ret == 0);
@@ -3514,14 +3385,6 @@ public_fREe(Void_t* mem)
 #if HAVE_MMAP
   if (chunk_is_mmapped(p))                       /* release mmapped memory. */
   {
-    /* see if the dynamic brk/mmap threshold needs adjusting */
-    if (!mp_.no_dyn_threshold
-	&& p->size > mp_.mmap_threshold
-        && p->size <= DEFAULT_MMAP_THRESHOLD_MAX)
-      {
-	mp_.mmap_threshold = chunksize (p);
-	mp_.trim_threshold = 2 * mp_.mmap_threshold;
-      }
     munmap_chunk(p);
     return;
   }
@@ -3576,7 +3439,7 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
      Therefore we can exclude some size values which might appear
      here by accident or by "design" from some intruder.  */
   if (__builtin_expect ((uintptr_t) oldp > (uintptr_t) -oldsize, 0)
-      || __builtin_expect (misaligned_chunk (oldp), 0))
+      || __builtin_expect ((uintptr_t) oldp & MALLOC_ALIGN_MASK, 0))
     {
       malloc_printerr (check_action, "realloc(): invalid pointer", oldmem);
       return NULL;
@@ -3626,29 +3489,6 @@ public_rEALLOc(Void_t* oldmem, size_t bytes)
   (void)mutex_unlock(&ar_ptr->mutex);
   assert(!newp || chunk_is_mmapped(mem2chunk(newp)) ||
 	 ar_ptr == arena_for_chunk(mem2chunk(newp)));
-
-  if (newp == NULL)
-    {
-      /* Try harder to allocate memory in other arenas.  */
-      newp = public_mALLOc(bytes);
-      if (newp != NULL)
-	{
-	  MALLOC_COPY (newp, oldmem, oldsize - 2 * SIZE_SZ);
-#if THREAD_STATS
-	  if(!mutex_trylock(&ar_ptr->mutex))
-	    ++(ar_ptr->stat_lock_direct);
-	  else {
-	    (void)mutex_lock(&ar_ptr->mutex);
-	    ++(ar_ptr->stat_lock_wait);
-	  }
-#else
-	  (void)mutex_lock(&ar_ptr->mutex);
-#endif
-	  _int_free(ar_ptr, oldmem);
-	  (void)mutex_unlock(&ar_ptr->mutex);
-	}
-    }
-
   return newp;
 }
 #ifdef libc_hidden_def
@@ -3836,18 +3676,14 @@ public_cALLOc(size_t n, size_t elem_size)
 
   /* Two optional cases in which clearing not necessary */
 #if HAVE_MMAP
-  if (chunk_is_mmapped (p))
-    {
-      if (__builtin_expect (perturb_byte, 0))
-	MALLOC_ZERO (mem, sz);
-      return mem;
-    }
+  if (chunk_is_mmapped(p))
+    return mem;
 #endif
 
   csz = chunksize(p);
 
 #if MORECORE_CLEARS
-  if (perturb_byte == 0 && (p == oldtop && csz > oldtopsize)) {
+  if (p == oldtop && csz > oldtopsize) {
     /* clear only the bytes from non-freshly-sbrked memory */
     csz = oldtopsize;
   }
@@ -3885,8 +3721,6 @@ public_cALLOc(size_t n, size_t elem_size)
   return mem;
 }
 
-#ifndef _LIBC
-
 Void_t**
 public_iCALLOc(size_t n, size_t elem_size, Void_t** chunks)
 {
@@ -3917,6 +3751,8 @@ public_iCOMALLOc(size_t n, size_t sizes[], Void_t** chunks)
   return m;
 }
 
+#ifndef _LIBC
+
 void
 public_cFREe(Void_t* m)
 {
@@ -3930,8 +3766,6 @@ public_mTRIm(size_t s)
 {
   int result;
 
-  if(__malloc_initialized < 0)
-    ptmalloc_init ();
   (void)mutex_lock(&main_arena.mutex);
   result = mTRIm(s);
   (void)mutex_unlock(&main_arena.mutex);
@@ -4016,7 +3850,7 @@ _int_malloc(mstate av, size_t bytes)
     can try it without checking, which saves some time on this fast path.
   */
 
-  if ((unsigned long)(nb) <= (unsigned long)(get_max_fast ())) {
+  if ((unsigned long)(nb) <= (unsigned long)(av->max_fast)) {
     long int idx = fastbin_index(nb);
     fb = &(av->fastbins[idx]);
     if ( (victim = *fb) != 0) {
@@ -4025,10 +3859,7 @@ _int_malloc(mstate av, size_t bytes)
 			 chunk2mem (victim));
       *fb = victim->fd;
       check_remalloced_chunk(av, victim, nb);
-      void *p = chunk2mem(victim);
-      if (__builtin_expect (perturb_byte, 0))
-	alloc_perturb (p, bytes);
-      return p;
+      return chunk2mem(victim);
     }
   }
 
@@ -4056,10 +3887,7 @@ _int_malloc(mstate av, size_t bytes)
         if (av != &main_arena)
 	  victim->size |= NON_MAIN_ARENA;
         check_malloced_chunk(av, victim, nb);
-	void *p = chunk2mem(victim);
-	if (__builtin_expect (perturb_byte, 0))
-	  alloc_perturb (p, bytes);
-	return p;
+        return chunk2mem(victim);
       }
     }
   }
@@ -4096,8 +3924,6 @@ _int_malloc(mstate av, size_t bytes)
 
   for(;;) {
 
-    int iters = 0;
-    bool any_larger = false;
     while ( (victim = unsorted_chunks(av)->bk) != unsorted_chunks(av)) {
       bck = victim->bk;
       if (__builtin_expect (victim->size <= 2 * SIZE_SZ, 0)
@@ -4132,10 +3958,7 @@ _int_malloc(mstate av, size_t bytes)
         set_foot(remainder, remainder_size);
 
         check_malloced_chunk(av, victim, nb);
-	void *p = chunk2mem(victim);
-	if (__builtin_expect (perturb_byte, 0))
-	  alloc_perturb (p, bytes);
-	return p;
+        return chunk2mem(victim);
       }
 
       /* remove from unsorted list */
@@ -4149,10 +3972,7 @@ _int_malloc(mstate av, size_t bytes)
 	if (av != &main_arena)
 	  victim->size |= NON_MAIN_ARENA;
         check_malloced_chunk(av, victim, nb);
-	void *p = chunk2mem(victim);
-	if (__builtin_expect (perturb_byte, 0))
-	  alloc_perturb (p, bytes);
-	return p;
+        return chunk2mem(victim);
       }
 
       /* place chunk in bin */
@@ -4193,12 +4013,6 @@ _int_malloc(mstate av, size_t bytes)
       victim->fd = fwd;
       fwd->bk = victim;
       bck->fd = victim;
-
-      if (size >= nb + MINSIZE)
-	any_larger = true;
-#define MAX_ITERS	10000
-      if (++iters >= MAX_ITERS)
-	break;
     }
 
     /*
@@ -4227,28 +4041,21 @@ _int_malloc(mstate av, size_t bytes)
           set_inuse_bit_at_offset(victim, size);
 	  if (av != &main_arena)
 	    victim->size |= NON_MAIN_ARENA;
+          check_malloced_chunk(av, victim, nb);
+          return chunk2mem(victim);
         }
         /* Split */
         else {
           remainder = chunk_at_offset(victim, nb);
-          /* We cannot assume the unsorted list is empty and therefore
-             have to perform a complete insert here.  */
-	  bck = unsorted_chunks(av);
-	  fwd = bck->fd;
-	  remainder->bk = bck;
-	  remainder->fd = fwd;
-	  bck->fd = remainder;
-	  fwd->bk = remainder;
+          unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+          remainder->bk = remainder->fd = unsorted_chunks(av);
           set_head(victim, nb | PREV_INUSE |
 		   (av != &main_arena ? NON_MAIN_ARENA : 0));
           set_head(remainder, remainder_size | PREV_INUSE);
           set_foot(remainder, remainder_size);
+          check_malloced_chunk(av, victim, nb);
+          return chunk2mem(victim);
         }
-	check_malloced_chunk(av, victim, nb);
-	void *p = chunk2mem(victim);
-	if (__builtin_expect (perturb_byte, 0))
-	  alloc_perturb (p, bytes);
-	return p;
       }
     }
 
@@ -4317,21 +4124,16 @@ _int_malloc(mstate av, size_t bytes)
           set_inuse_bit_at_offset(victim, size);
 	  if (av != &main_arena)
 	    victim->size |= NON_MAIN_ARENA;
+          check_malloced_chunk(av, victim, nb);
+          return chunk2mem(victim);
         }
 
         /* Split */
         else {
           remainder = chunk_at_offset(victim, nb);
 
-	  /* We cannot assume the unsorted list is empty and therefore
-	     have to perform a complete insert here.  */
-	  bck = unsorted_chunks(av);
-	  fwd = bck->fd;
-	  remainder->bk = bck;
-	  remainder->fd = fwd;
-	  bck->fd = remainder;
-	  fwd->bk = remainder;
-
+          unsorted_chunks(av)->bk = unsorted_chunks(av)->fd = remainder;
+          remainder->bk = remainder->fd = unsorted_chunks(av);
           /* advertise as last remainder */
           if (in_smallbin_range(nb))
             av->last_remainder = remainder;
@@ -4340,12 +4142,9 @@ _int_malloc(mstate av, size_t bytes)
 		   (av != &main_arena ? NON_MAIN_ARENA : 0));
           set_head(remainder, remainder_size | PREV_INUSE);
           set_foot(remainder, remainder_size);
+          check_malloced_chunk(av, victim, nb);
+          return chunk2mem(victim);
         }
-	check_malloced_chunk(av, victim, nb);
-	void *p = chunk2mem(victim);
-	if (__builtin_expect (perturb_byte, 0))
-	  alloc_perturb (p, bytes);
-	return p;
       }
     }
 
@@ -4377,10 +4176,7 @@ _int_malloc(mstate av, size_t bytes)
       set_head(remainder, remainder_size | PREV_INUSE);
 
       check_malloced_chunk(av, victim, nb);
-      void *p = chunk2mem(victim);
-      if (__builtin_expect (perturb_byte, 0))
-	alloc_perturb (p, bytes);
-      return p;
+      return chunk2mem(victim);
     }
 
     /*
@@ -4398,12 +4194,8 @@ _int_malloc(mstate av, size_t bytes)
     /*
        Otherwise, relay to handle system-dependent cases
     */
-    else {
-      void *p = sYSMALLOc(nb, av);
-      if (__builtin_expect (perturb_byte, 0))
-	alloc_perturb (p, bytes);
-      return p;
-    }
+    else
+      return sYSMALLOc(nb, av);
   }
 }
 
@@ -4434,19 +4226,13 @@ _int_free(mstate av, Void_t* mem)
      Therefore we can exclude some size values which might appear
      here by accident or by "design" from some intruder.  */
   if (__builtin_expect ((uintptr_t) p > (uintptr_t) -size, 0)
-      || __builtin_expect (misaligned_chunk (p), 0))
+      || __builtin_expect ((uintptr_t) p & MALLOC_ALIGN_MASK, 0))
     {
       errstr = "free(): invalid pointer";
     errout:
       malloc_printerr (check_action, errstr, mem);
       return;
     }
-  /* We know that each chunk is at least MINSIZE bytes in size.  */
-  if (__builtin_expect (size < MINSIZE, 0))
-    {
-      errstr = "free(): invalid size";
-      goto errout;
-    }
 
   check_inuse_chunk(av, p);
 
@@ -4455,7 +4241,7 @@ _int_free(mstate av, Void_t* mem)
     and used quickly in malloc.
   */
 
-  if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
+  if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
 
 #if TRIM_FASTBINS
       /*
@@ -4483,10 +4269,6 @@ _int_free(mstate av, Void_t* mem)
 	errstr = "double free or corruption (fasttop)";
 	goto errout;
       }
-
-    if (__builtin_expect (perturb_byte, 0))
-      free_perturb (mem, size - SIZE_SZ);
-
     p->fd = *fb;
     *fb = p;
   }
@@ -4528,9 +4310,6 @@ _int_free(mstate av, Void_t* mem)
 	goto errout;
       }
 
-    if (__builtin_expect (perturb_byte, 0))
-      free_perturb (mem, size - SIZE_SZ);
-
     /* consolidate backward */
     if (!prev_inuse(p)) {
       prevsize = p->prev_size;
@@ -4671,7 +4450,7 @@ static void malloc_consolidate(av) mstate av;
     yet been initialized, in which case do so below
   */
 
-  if (get_max_fast () != 0) {
+  if (av->max_fast != 0) {
     clear_fastchunks(av);
 
     unsorted_bin = unsorted_chunks(av);
@@ -4684,7 +4463,7 @@ static void malloc_consolidate(av) mstate av;
       reused anyway.
     */
 
-    maxfb = &(av->fastbins[fastbin_index(get_max_fast ())]);
+    maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
     fb = &(av->fastbins[0]);
     do {
       if ( (p = *fb) != 0) {
@@ -4780,7 +4559,7 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
   oldsize = chunksize(oldp);
 
   /* Simple tests for old block integrity.  */
-  if (__builtin_expect (misaligned_chunk (oldp), 0))
+  if (__builtin_expect ((uintptr_t) oldp & MALLOC_ALIGN_MASK, 0))
     {
       errstr = "realloc(): invalid pointer";
     errout:
@@ -4790,7 +4569,7 @@ _int_realloc(mstate av, Void_t* oldmem, size_t bytes)
   if (__builtin_expect (oldp->size <= 2 * SIZE_SZ, 0)
       || __builtin_expect (oldsize >= av->system_mem, 0))
     {
-      errstr = "realloc(): invalid old size";
+      errstr = "realloc(): invalid size";
       goto errout;
     }
 
@@ -5147,7 +4926,6 @@ Void_t* cALLOc(n_elements, elem_size) size_t n_elements; size_t elem_size;
 }
 #endif /* 0 */
 
-#ifndef _LIBC
 /*
   ------------------------- independent_calloc -------------------------
 */
@@ -5311,7 +5089,6 @@ mstate av; size_t n_elements; size_t* sizes; int opts; Void_t* chunks[];
 
   return marray;
 }
-#endif /* _LIBC */
 
 
 /*
@@ -5548,7 +5325,7 @@ int mALLOPt(param_number, value) int param_number; int value;
   switch(param_number) {
   case M_MXFAST:
     if (value >= 0 && value <= MAX_FAST_SIZE) {
-      set_max_fast(value);
+      set_max_fast(av, value);
     }
     else
       res = 0;
@@ -5556,12 +5333,10 @@ int mALLOPt(param_number, value) int param_number; int value;
 
   case M_TRIM_THRESHOLD:
     mp_.trim_threshold = value;
-    mp_.no_dyn_threshold = 1;
     break;
 
   case M_TOP_PAD:
     mp_.top_pad = value;
-    mp_.no_dyn_threshold = 1;
     break;
 
   case M_MMAP_THRESHOLD:
@@ -5572,7 +5347,6 @@ int mALLOPt(param_number, value) int param_number; int value;
     else
 #endif
       mp_.mmap_threshold = value;
-      mp_.no_dyn_threshold = 1;
     break;
 
   case M_MMAP_MAX:
@@ -5582,16 +5356,11 @@ int mALLOPt(param_number, value) int param_number; int value;
     else
 #endif
       mp_.n_mmaps_max = value;
-      mp_.no_dyn_threshold = 1;
     break;
 
   case M_CHECK_ACTION:
     check_action = value;
     break;
-
-  case M_PERTURB:
-    perturb_byte = value;
-    break;
   }
   (void)mutex_unlock(&av->mutex);
   return res;
@@ -5739,14 +5508,10 @@ int mALLOPt(param_number, value) int param_number; int value;
 
 /* Helper code.  */
 
-extern char **__libc_argv attribute_hidden;
-
 static void
 malloc_printerr(int action, const char *str, void *ptr)
 {
-  if ((action & 5) == 5)
-    __libc_message (action & 2, "%s\n", str);
-  else if (action & 1)
+  if (action & 1)
     {
       char buf[2 * sizeof (uintptr_t) + 1];
 
@@ -5756,8 +5521,9 @@ malloc_printerr(int action, const char *str, void *ptr)
 	*--cp = '0';
 
       __libc_message (action & 2,
-		      "*** glibc detected *** %s: %s: 0x%s ***\n",
-		      __libc_argv[0] ?: "<unknown>", str, cp);
+		      action & 4
+		      ? "%s\n" : "*** glibc detected *** %s: 0x%s ***\n",
+		      str, cp);
     }
   else if (action & 2)
     abort ();
diff --git a/malloc/malloc.h b/malloc/malloc.h
index 1340aa15bc..753539e7b0 100644
--- a/malloc/malloc.h
+++ b/malloc/malloc.h
@@ -1,5 +1,5 @@
 /* Prototypes and definition for malloc implementation.
-   Copyright (C) 1996,97,99,2000,2002-2004,2005 Free Software Foundation, Inc.
+   Copyright (C) 1996,97,99,2000,2002,2003,2004 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,16 +20,59 @@
 #ifndef _MALLOC_H
 #define _MALLOC_H 1
 
+#ifdef _LIBC
 #include <features.h>
-#include <stddef.h>
+#endif
+
+/*
+  $Id$
+  `ptmalloc2', a malloc implementation for multiple threads without
+  lock contention, by Wolfram Gloger <wg@malloc.de>.
+
+  VERSION 2.7.0
+
+  This work is mainly derived from malloc-2.7.0 by Doug Lea
+  <dl@cs.oswego.edu>, which is available from:
+
+                 ftp://gee.cs.oswego.edu/pub/misc/malloc.c
+
+  This trimmed-down header file only provides function prototypes and
+  the exported data structures.  For more detailed function
+  descriptions and compile-time options, see the source file
+  `malloc.c'.
+*/
+
+#if defined(__STDC__) || defined (__cplusplus)
+# include <stddef.h>
 # define __malloc_ptr_t  void *
+#else
+# undef  size_t
+# define size_t          unsigned int
+# undef  ptrdiff_t
+# define ptrdiff_t       int
+# define __malloc_ptr_t  char *
+#endif
 
+#ifdef _LIBC
 /* Used by GNU libc internals. */
-#define __malloc_size_t size_t
-#define __malloc_ptrdiff_t ptrdiff_t
+# define __malloc_size_t size_t
+# define __malloc_ptrdiff_t ptrdiff_t
+#elif !defined __attribute_malloc__
+# define __attribute_malloc__
+#endif
 
 #ifdef __GNUC__
 
+/* GCC can always grok prototypes.  For C++ programs we add throw()
+   to help it optimize the function calls.  But this works only with
+   gcc 2.8.x and egcs.  */
+# ifndef __THROW
+#  if defined __cplusplus && (__GNUC__ >= 3 || __GNUC_MINOR__ >= 8)
+#   define __THROW	throw ()
+#  else
+#   define __THROW
+#  endif
+# endif
 # define __MALLOC_P(args)	args __THROW
 /* This macro will be used for functions which might take C++ callback
    functions.  */
@@ -37,51 +80,78 @@
 
 #else	/* Not GCC.  */
 
-# define __MALLOC_P(args)	args
-# define __MALLOC_PMT(args)	args
+# define __THROW
+
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+
+#  define __MALLOC_P(args)	args
+#  define __MALLOC_PMT(args)	args
+
+#  ifndef __const
+#   define __const	 const
+#  endif
+
+# else	/* Not ANSI C or C++.  */
+
+#  define __MALLOC_P(args)	()	/* No prototypes.  */
+#  define __MALLOC_PMT(args)	()
+
+#  ifndef __const
+#   define __const
+#  endif
+
+# endif	/* ANSI C or C++.  */
 
 #endif	/* GCC.  */
 
+#ifndef NULL
+# ifdef __cplusplus
+#  define NULL	0
+# else
+#  define NULL	((__malloc_ptr_t) 0)
+# endif
+#endif
 
-__BEGIN_DECLS
+#ifdef __cplusplus
+extern "C" {
+#endif
 
 /* Allocate SIZE bytes of memory.  */
-extern void *malloc __MALLOC_P ((size_t __size)) __attribute_malloc__ __wur;
+extern __malloc_ptr_t malloc __MALLOC_P ((size_t __size)) __attribute_malloc__;
 
 /* Allocate NMEMB elements of SIZE bytes each, all initialized to 0.  */
-extern void *calloc __MALLOC_P ((size_t __nmemb, size_t __size))
-       __attribute_malloc__ __wur;
+extern __malloc_ptr_t calloc __MALLOC_P ((size_t __nmemb, size_t __size))
+       __attribute_malloc__;
 
 /* Re-allocate the previously allocated block in __ptr, making the new
    block SIZE bytes long.  */
-extern void *realloc __MALLOC_P ((void *__ptr, size_t __size))
-       __attribute_malloc__ __attribute_warn_unused_result__;
+extern __malloc_ptr_t realloc __MALLOC_P ((__malloc_ptr_t __ptr,
+					   size_t __size))
+       __attribute_malloc__;
 
 /* Free a block allocated by `malloc', `realloc' or `calloc'.  */
-extern void free __MALLOC_P ((void *__ptr));
+extern void free __MALLOC_P ((__malloc_ptr_t __ptr));
 
 /* Free a block allocated by `calloc'. */
-extern void cfree __MALLOC_P ((void *__ptr));
+extern void cfree __MALLOC_P ((__malloc_ptr_t __ptr));
 
 /* Allocate SIZE bytes allocated to ALIGNMENT bytes.  */
-extern void *memalign __MALLOC_P ((size_t __alignment, size_t __size))
-       __attribute_malloc__ __wur;
+extern __malloc_ptr_t memalign __MALLOC_P ((size_t __alignment, size_t __size));
 
 /* Allocate SIZE bytes on a page boundary.  */
-extern void *valloc __MALLOC_P ((size_t __size))
-       __attribute_malloc__ __wur;
+extern __malloc_ptr_t valloc __MALLOC_P ((size_t __size)) __attribute_malloc__;
 
 /* Equivalent to valloc(minimum-page-that-holds(n)), that is, round up
    __size to nearest pagesize. */
-extern void * pvalloc __MALLOC_P ((size_t __size))
-       __attribute_malloc__ __wur;
+extern __malloc_ptr_t  pvalloc __MALLOC_P ((size_t __size))
+       __attribute_malloc__;
 
 /* Underlying allocation function; successive calls should return
    contiguous pieces of memory.  */
-extern void *(*__morecore) __MALLOC_PMT ((ptrdiff_t __size));
+extern __malloc_ptr_t (*__morecore) __MALLOC_PMT ((ptrdiff_t __size));
 
 /* Default value of `__morecore'.  */
-extern void *__default_morecore __MALLOC_P ((ptrdiff_t __size))
+extern __malloc_ptr_t __default_morecore __MALLOC_P ((ptrdiff_t __size))
        __attribute_malloc__;
 
 /* SVID2/XPG mallinfo structure */
@@ -122,7 +192,6 @@ extern struct mallinfo mallinfo __MALLOC_P ((void));
 #define M_MMAP_THRESHOLD    -3
 #define M_MMAP_MAX          -4
 #define M_CHECK_ACTION      -5
-#define M_PERTURB	    -6
 
 /* General SVID/XPG interface to tunable parameters. */
 extern int mallopt __MALLOC_P ((int __param, int __val));
@@ -133,38 +202,41 @@ extern int malloc_trim __MALLOC_P ((size_t __pad));
 
 /* Report the number of usable allocated bytes associated with allocated
    chunk __ptr. */
-extern size_t malloc_usable_size __MALLOC_P ((void *__ptr));
+extern size_t malloc_usable_size __MALLOC_P ((__malloc_ptr_t __ptr));
 
 /* Prints brief summary statistics on stderr. */
 extern void malloc_stats __MALLOC_P ((void));
 
 /* Record the state of all malloc variables in an opaque data structure. */
-extern void *malloc_get_state __MALLOC_P ((void));
+extern __malloc_ptr_t malloc_get_state __MALLOC_P ((void));
 
 /* Restore the state of all malloc variables from data obtained with
    malloc_get_state(). */
-extern int malloc_set_state __MALLOC_P ((void *__ptr));
+extern int malloc_set_state __MALLOC_P ((__malloc_ptr_t __ptr));
 
 /* Called once when malloc is initialized; redefining this variable in
    the application provides the preferred way to set up the hook
    pointers. */
 extern void (*__malloc_initialize_hook) __MALLOC_PMT ((void));
 /* Hooks for debugging and user-defined versions. */
-extern void (*__free_hook) __MALLOC_PMT ((void *__ptr,
+extern void (*__free_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
 					__const __malloc_ptr_t));
-extern void *(*__malloc_hook) __MALLOC_PMT ((size_t __size,
-					     __const __malloc_ptr_t));
-extern void *(*__realloc_hook) __MALLOC_PMT ((void *__ptr, size_t __size,
-					      __const __malloc_ptr_t));
-extern void *(*__memalign_hook) __MALLOC_PMT ((size_t __alignment,
-					       size_t __size,
-					       __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__malloc_hook) __MALLOC_PMT ((size_t __size,
+						    __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__realloc_hook) __MALLOC_PMT ((__malloc_ptr_t __ptr,
+						     size_t __size,
+						     __const __malloc_ptr_t));
+extern __malloc_ptr_t (*__memalign_hook) __MALLOC_PMT ((size_t __alignment,
+						      size_t __size,
+						      __const __malloc_ptr_t));
 extern void (*__after_morecore_hook) __MALLOC_PMT ((void));
 
 /* Activate a standard set of debugging hooks. */
 extern void __malloc_check_init __MALLOC_P ((void));
 
 
-__END_DECLS
+#ifdef __cplusplus
+} /* end of extern "C" */
+#endif
 
 #endif /* malloc.h */
diff --git a/malloc/mcheck.c b/malloc/mcheck.c
index 9f88843445..02379d219d 100644
--- a/malloc/mcheck.c
+++ b/malloc/mcheck.c
@@ -24,25 +24,9 @@
 # include <mcheck.h>
 # include <stdint.h>
 # include <stdio.h>
-# include <stdlib.h>
 # include <libintl.h>
 #endif
 
-#ifdef _LIBC
-extern __typeof (malloc) __libc_malloc;
-extern __typeof (free) __libc_free;
-extern __typeof (realloc) __libc_realloc;
-libc_hidden_proto (__libc_malloc)
-libc_hidden_proto (__libc_realloc)
-libc_hidden_proto (__libc_free)
-libc_hidden_proto (__libc_memalign)
-#else
-# define __libc_malloc(sz) malloc (sz)
-# define __libc_free(ptr) free (ptr)
-# define __libc_realloc(ptr, sz) realloc (ptr, sz)
-# define __libc_memalign(al, sz) memalign (al, sz)
-#endif
-
 /* Old hook values.  */
 static void (*old_free_hook) (__ptr_t ptr, __const __ptr_t);
 static __ptr_t (*old_malloc_hook) (__malloc_size_t size, const __ptr_t);
@@ -213,7 +197,7 @@ freehook (__ptr_t ptr, const __ptr_t caller)
   if (old_free_hook != NULL)
     (*old_free_hook) (ptr, caller);
   else
-    __libc_free (ptr);
+    free (ptr);
   __free_hook = freehook;
 }
 
@@ -230,7 +214,7 @@ mallochook (__malloc_size_t size, const __ptr_t caller)
     hdr = (struct hdr *) (*old_malloc_hook) (sizeof (struct hdr) + size + 1,
 					     caller);
   else
-    hdr = (struct hdr *) __libc_malloc (sizeof (struct hdr) + size + 1);
+    hdr = (struct hdr *) malloc (sizeof (struct hdr) + size + 1);
   __malloc_hook = mallochook;
   if (hdr == NULL)
     return NULL;
@@ -261,7 +245,7 @@ memalignhook (__malloc_size_t alignment, __malloc_size_t size,
   if (old_memalign_hook != NULL)
     block = (*old_memalign_hook) (alignment, slop + size + 1, caller);
   else
-    block = __libc_memalign (alignment, slop + size + 1);
+    block = memalign (alignment, slop + size + 1);
   __memalign_hook = memalignhook;
   if (block == NULL)
     return NULL;
@@ -310,8 +294,8 @@ reallochook (__ptr_t ptr, __malloc_size_t size, const __ptr_t caller)
 					      sizeof (struct hdr) + size + 1,
 					      caller);
   else
-    hdr = (struct hdr *) __libc_realloc ((__ptr_t) hdr,
-					 sizeof (struct hdr) + size + 1);
+    hdr = (struct hdr *) realloc ((__ptr_t) hdr,
+				  sizeof (struct hdr) + size + 1);
   __free_hook = freehook;
   __malloc_hook = mallochook;
   __memalign_hook = memalignhook;
@@ -371,8 +355,8 @@ mcheck (func)
   if (__malloc_initialized <= 0 && !mcheck_used)
     {
       /* We call malloc() once here to ensure it is initialized.  */
-      void *p = __libc_malloc (0);
-      __libc_free (p);
+      void *p = malloc (0);
+      free (p);
 
       old_free_hook = __free_hook;
       __free_hook = freehook;
diff --git a/malloc/memusage.c b/malloc/memusage.c
index 16fa09060a..b552ec37b0 100644
--- a/malloc/memusage.c
+++ b/malloc/memusage.c
@@ -1,5 +1,5 @@
 /* Profile heap and stack memory usage of running program.
-   Copyright (C) 1998-2002, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1998-2002, 2004 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
@@ -18,13 +18,11 @@
    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
    02111-1307 USA.  */
 
-#include <atomic.h>
 #include <dlfcn.h>
 #include <errno.h>
 #include <fcntl.h>
 #include <inttypes.h>
 #include <signal.h>
-#include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -45,7 +43,7 @@ static void (*freep) (void *);
 static void *(*mmapp) (void *, size_t, int, int, int, off_t);
 static void *(*mmap64p) (void *, size_t, int, int, int, off64_t);
 static int (*munmapp) (void *, size_t);
-static void *(*mremapp) (void *, size_t, size_t, int, void *);
+static void *(*mremapp) (void *, size_t, size_t, int);
 
 enum
 {
@@ -71,23 +69,24 @@ struct header
 #define MAGIC 0xfeedbeaf
 
 
-static memusage_cntr_t calls[idx_last];
-static memusage_cntr_t failed[idx_last];
-static memusage_size_t total[idx_last];
-static memusage_size_t grand_total;
-static memusage_cntr_t histogram[65536 / 16];
-static memusage_cntr_t large;
-static memusage_cntr_t calls_total;
-static memusage_cntr_t inplace;
-static memusage_cntr_t decreasing;
-static memusage_cntr_t realloc_free;
-static memusage_cntr_t inplace_mremap;
-static memusage_cntr_t decreasing_mremap;
-static memusage_size_t current_heap;
-static memusage_size_t peak_use[3];
-static __thread uintptr_t start_sp;
+static unsigned long int calls[idx_last];
+static unsigned long int failed[idx_last];
+static unsigned long long int total[idx_last];
+static unsigned long long int grand_total;
+static unsigned long int histogram[65536 / 16];
+static unsigned long int large;
+static unsigned long int calls_total;
+static unsigned long int inplace;
+static unsigned long int decreasing;
+static unsigned long int inplace_mremap;
+static unsigned long int decreasing_mremap;
+static long int current_use[2];
+static long int peak_use[3];
+static uintptr_t start_sp;
 
 /* A few macros to make the source more readable.  */
+#define current_heap	current_use[0]
+#define current_stack	current_use[1]
 #define peak_heap	peak_use[0]
 #define peak_stack	peak_use[1]
 #define peak_total	peak_use[2]
@@ -104,14 +103,14 @@ extern const char *__progname;
 
 struct entry
 {
-  uint64_t heap;
-  uint64_t stack;
+  size_t heap;
+  size_t stack;
   uint32_t time_low;
   uint32_t time_high;
 };
 
-static struct entry buffer[2 * DEFAULT_BUFFER_SIZE];
-static uatomic32_t buffer_cnt;
+static struct entry buffer[DEFAULT_BUFFER_SIZE];
+static size_t buffer_cnt;
 static struct entry first;
 
 
@@ -119,6 +118,8 @@ static struct entry first;
 static void
 update_data (struct header *result, size_t len, size_t old_len)
 {
+  long int total_use;
+
   if (result != NULL)
     {
       /* Record the information we need and mark the block using a
@@ -128,60 +129,38 @@ update_data (struct header *result, size_t len, size_t old_len)
     }
 
   /* Compute current heap usage and compare it with the maximum value.  */
-  memusage_size_t heap
-    = atomic_exchange_and_add (&current_heap, len - old_len) + len - old_len;
-  atomic_max (&peak_heap, heap);
-
-  /* Compute current stack usage and compare it with the maximum
-     value.  The base stack pointer might not be set if this is not
-     the main thread and it is the first call to any of these
-     functions.  */
-  if (__builtin_expect (!start_sp, 0))
-    start_sp = GETSP ();
-
-  uintptr_t sp = GETSP ();
+  current_heap += len - old_len;
+  if (current_heap > peak_heap)
+    peak_heap = current_heap;
+
+  /* Compute current stack usage and compare it with the maximum value.  */
 #ifdef STACK_GROWS_UPWARD
-  /* This can happen in threads where we didn't catch the thread's
-     stack early enough.  */
-  if (__builtin_expect (sp < start_sp, 0))
-    start_sp = sp;
-  size_t current_stack = sp - start_sp;
+  current_stack = GETSP () - start_sp;
 #else
-  /* This can happen in threads where we didn't catch the thread's
-     stack early enough.  */
-  if (__builtin_expect (sp > start_sp, 0))
-    start_sp = sp;
-  size_t current_stack = start_sp - sp;
+  current_stack = start_sp - GETSP ();
 #endif
-  atomic_max (&peak_stack, current_stack);
+  if (current_stack > peak_stack)
+    peak_stack = current_stack;
 
   /* Add up heap and stack usage and compare it with the maximum value.  */
-  atomic_max (&peak_total, heap + current_stack);
+  total_use = current_heap + current_stack;
+  if (total_use > peak_total)
+    peak_total = total_use;
 
   /* Store the value only if we are writing to a file.  */
   if (fd != -1)
     {
-      uatomic32_t idx = atomic_exchange_and_add (&buffer_cnt, 1);
-      if (idx >= 2 * buffer_size)
-	{
-	  /* We try to reset the counter to the correct range.  If
-	     this fails because of another thread increasing the
-	     counter it does not matter since that thread will take
-	     care of the correction.  */
-	  unsigned int reset = idx - 2 * buffer_size;
-	  atomic_compare_and_exchange_val_acq (&buffer_size, reset, idx);
-	  idx = reset;
-	}
-
-      buffer[idx].heap = current_heap;
-      buffer[idx].stack = current_stack;
-      GETTIME (buffer[idx].time_low, buffer[idx].time_high);
+      buffer[buffer_cnt].heap = current_heap;
+      buffer[buffer_cnt].stack = current_stack;
+      GETTIME (buffer[buffer_cnt].time_low, buffer[buffer_cnt].time_high);
+      ++buffer_cnt;
 
       /* Write out buffer if it is full.  */
-      if (idx + 1 == buffer_size)
-	write (fd, buffer, buffer_size * sizeof (struct entry));
-      else if (idx + 1 == 2 * buffer_size)
-	write (fd, &buffer[buffer_size], buffer_size * sizeof (struct entry));
+      if (buffer_cnt == buffer_size)
+	{
+	  write (fd, buffer, buffer_cnt * sizeof (struct entry));
+	  buffer_cnt = 0;
+	}
     }
 }
 
@@ -228,8 +207,8 @@ me (void)
   mmap64p =
     (void *(*) (void *, size_t, int, int, int, off64_t)) dlsym (RTLD_NEXT,
 								"mmap64");
-  mremapp = (void *(*) (void *, size_t, size_t, int, void *)) dlsym (RTLD_NEXT,
-								     "mremap");
+  mremapp = (void *(*) (void *, size_t, size_t, int)) dlsym (RTLD_NEXT,
+							     "mremap");
   munmapp = (int (*) (void *, size_t)) dlsym (RTLD_NEXT, "munmap");
   initialized = 1;
 
@@ -268,7 +247,6 @@ me (void)
 	      GETTIME (first.time_low, first.time_high);
 	      /* Write it two times since we need the starting and end time. */
 	      write (fd, &first, sizeof (first));
-	      write (fd, &first, sizeof (first));
 
 	      /* Determine the buffer size.  We use the default if the
 		 environment variable is not present.  */
@@ -339,24 +317,24 @@ malloc (size_t len)
     return (*mallocp) (len);
 
   /* Keep track of number of calls.  */
-  atomic_increment (&calls[idx_malloc]);
+  ++calls[idx_malloc];
   /* Keep track of total memory consumption for `malloc'.  */
-  atomic_add (&total[idx_malloc], len);
+  total[idx_malloc] += len;
   /* Keep track of total memory requirement.  */
-  atomic_add (&grand_total, len);
+  grand_total += len;
   /* Remember the size of the request.  */
   if (len < 65536)
-    atomic_increment (&histogram[len / 16]);
+    ++histogram[len / 16];
   else
-    atomic_increment (&large);
+    ++large;
   /* Total number of calls of any of the functions.  */
-  atomic_increment (&calls_total);
+  ++calls_total;
 
   /* Do the real work.  */
   result = (struct header *) (*mallocp) (len + sizeof (struct header));
   if (result == NULL)
     {
-      atomic_increment (&failed[idx_malloc]);
+      ++failed[idx_malloc];
       return NULL;
     }
 
@@ -405,53 +383,36 @@ realloc (void *old, size_t len)
     }
 
   /* Keep track of number of calls.  */
-  atomic_increment (&calls[idx_realloc]);
+  ++calls[idx_realloc];
   if (len > old_len)
     {
       /* Keep track of total memory consumption for `realloc'.  */
-      atomic_add (&total[idx_realloc], len - old_len);
+      total[idx_realloc] += len - old_len;
       /* Keep track of total memory requirement.  */
-      atomic_add (&grand_total, len - old_len);
-    }
-
-  if (len == 0 && old != NULL)
-    {
-      /* Special case.  */
-      atomic_increment (&realloc_free);
-      /* Keep track of total memory freed using `free'.  */
-      atomic_add (&total[idx_free], real->length);
-
-      /* Update the allocation data and write out the records if necessary.  */
-      update_data (NULL, 0, old_len);
-
-      /* Do the real work.  */
-      (*freep) (real);
-
-      return NULL;
+      grand_total += len - old_len;
     }
-
   /* Remember the size of the request.  */
   if (len < 65536)
-    atomic_increment (&histogram[len / 16]);
+    ++histogram[len / 16];
   else
-    atomic_increment (&large);
+    ++large;
   /* Total number of calls of any of the functions.  */
-  atomic_increment (&calls_total);
+  ++calls_total;
 
   /* Do the real work.  */
   result = (struct header *) (*reallocp) (real, len + sizeof (struct header));
   if (result == NULL)
     {
-      atomic_increment (&failed[idx_realloc]);
+      ++failed[idx_realloc];
       return NULL;
     }
 
   /* Record whether the reduction/increase happened in place.  */
   if (real == result)
-    atomic_increment (&inplace);
+    ++inplace;
   /* Was the buffer increased?  */
   if (old_len > len)
-    atomic_increment (&decreasing);
+    ++decreasing;
 
   /* Update the allocation data and write out the records if necessary.  */
   update_data (result, len, old_len);
@@ -482,16 +443,16 @@ calloc (size_t n, size_t len)
     return (*callocp) (n, len);
 
   /* Keep track of number of calls.  */
-  atomic_increment (&calls[idx_calloc]);
+  ++calls[idx_calloc];
   /* Keep track of total memory consumption for `calloc'.  */
-  atomic_add (&total[idx_calloc], size);
+  total[idx_calloc] += size;
   /* Keep track of total memory requirement.  */
-  atomic_add (&grand_total, size);
+  grand_total += size;
   /* Remember the size of the request.  */
   if (size < 65536)
-    atomic_increment (&histogram[size / 16]);
+    ++histogram[size / 16];
   else
-    atomic_increment (&large);
+    ++large;
   /* Total number of calls of any of the functions.  */
   ++calls_total;
 
@@ -499,7 +460,7 @@ calloc (size_t n, size_t len)
   result = (struct header *) (*mallocp) (size + sizeof (struct header));
   if (result == NULL)
     {
-      atomic_increment (&failed[idx_calloc]);
+      ++failed[idx_calloc];
       return NULL;
     }
 
@@ -536,7 +497,7 @@ free (void *ptr)
   /* `free (NULL)' has no effect.  */
   if (ptr == NULL)
     {
-      atomic_increment (&calls[idx_free]);
+      ++calls[idx_free];
       return;
     }
 
@@ -550,9 +511,9 @@ free (void *ptr)
     }
 
   /* Keep track of number of calls.  */
-  atomic_increment (&calls[idx_free]);
+  ++calls[idx_free];
   /* Keep track of total memory freed using `free'.  */
-  atomic_add (&total[idx_free], real->length);
+  total[idx_free] += real->length;
 
   /* Update the allocation data and write out the records if necessary.  */
   update_data (NULL, 0, real->length);
@@ -586,22 +547,22 @@ mmap (void *start, size_t len, int prot, int flags, int fd, off_t offset)
 		 ? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
 
       /* Keep track of number of calls.  */
-      atomic_increment (&calls[idx]);
+      ++calls[idx];
       /* Keep track of total memory consumption for `malloc'.  */
-      atomic_add (&total[idx], len);
+      total[idx] += len;
       /* Keep track of total memory requirement.  */
-      atomic_add (&grand_total, len);
+      grand_total += len;
       /* Remember the size of the request.  */
       if (len < 65536)
-	atomic_increment (&histogram[len / 16]);
+	++histogram[len / 16];
       else
-	atomic_increment (&large);
+	++large;
       /* Total number of calls of any of the functions.  */
-      atomic_increment (&calls_total);
+      ++calls_total;
 
       /* Check for failures.  */
       if (result == NULL)
-	atomic_increment (&failed[idx]);
+	++failed[idx];
       else if (idx == idx_mmap_w)
 	/* Update the allocation data and write out the records if
 	   necessary.  Note the first parameter is NULL which means
@@ -638,22 +599,22 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
 		 ? idx_mmap_a : prot & PROT_WRITE ? idx_mmap_w : idx_mmap_r);
 
       /* Keep track of number of calls.  */
-      atomic_increment (&calls[idx]);
+      ++calls[idx];
       /* Keep track of total memory consumption for `malloc'.  */
-      atomic_add (&total[idx], len);
+      total[idx] += len;
       /* Keep track of total memory requirement.  */
-      atomic_add (&grand_total, len);
+      grand_total += len;
       /* Remember the size of the request.  */
       if (len < 65536)
-	atomic_increment (&histogram[len / 16]);
+	++histogram[len / 16];
       else
-	atomic_increment (&large);
+	++large;
       /* Total number of calls of any of the functions.  */
-      atomic_increment (&calls_total);
+      ++calls_total;
 
       /* Check for failures.  */
       if (result == NULL)
-	atomic_increment (&failed[idx]);
+	++failed[idx];
       else if (idx == idx_mmap_w)
 	/* Update the allocation data and write out the records if
 	   necessary.  Note the first parameter is NULL which means
@@ -669,14 +630,9 @@ mmap64 (void *start, size_t len, int prot, int flags, int fd, off64_t offset)
 /* `mmap' replacement.  We do not have to keep track of the sizesince
    `munmap' will get it as a parameter.  */
 void *
-mremap (void *start, size_t old_len, size_t len, int flags,  ...)
+mremap (void *start, size_t old_len, size_t len, int flags)
 {
   void *result = NULL;
-  va_list ap;
-
-  va_start (ap, flags);
-  void *newaddr = (flags & MREMAP_FIXED) ? va_arg (ap, void *) : NULL;
-  va_end (ap);
 
   /* Determine real implementation if not already happened.  */
   if (__builtin_expect (initialized <= 0, 0))
@@ -687,38 +643,38 @@ mremap (void *start, size_t old_len, size_t len, int flags,  ...)
     }
 
   /* Always get a block.  We don't need extra memory.  */
-  result = (*mremapp) (start, old_len, len, flags, newaddr);
+  result = (*mremapp) (start, old_len, len, flags);
 
   if (!not_me && trace_mmap)
     {
       /* Keep track of number of calls.  */
-      atomic_increment (&calls[idx_mremap]);
+      ++calls[idx_mremap];
       if (len > old_len)
 	{
 	  /* Keep track of total memory consumption for `malloc'.  */
-	  atomic_add (&total[idx_mremap], len - old_len);
+	  total[idx_mremap] += len - old_len;
 	  /* Keep track of total memory requirement.  */
-	  atomic_add (&grand_total, len - old_len);
+	  grand_total += len - old_len;
 	}
       /* Remember the size of the request.  */
       if (len < 65536)
-	atomic_increment (&histogram[len / 16]);
+	++histogram[len / 16];
       else
-	atomic_increment (&large);
+	++large;
       /* Total number of calls of any of the functions.  */
-      atomic_increment (&calls_total);
+      ++calls_total;
 
       /* Check for failures.  */
       if (result == NULL)
-	atomic_increment (&failed[idx_mremap]);
+	++failed[idx_mremap];
       else
 	{
 	  /* Record whether the reduction/increase happened in place.  */
 	  if (start == result)
-	    atomic_increment (&inplace_mremap);
+	    ++inplace_mremap;
 	  /* Was the buffer increased?  */
 	  if (old_len > len)
-	    atomic_increment (&decreasing_mremap);
+	    ++decreasing_mremap;
 
 	  /* Update the allocation data and write out the records if
 	     necessary.  Note the first parameter is NULL which means
@@ -752,19 +708,19 @@ munmap (void *start, size_t len)
   if (!not_me && trace_mmap)
     {
       /* Keep track of number of calls.  */
-      atomic_increment (&calls[idx_munmap]);
+      ++calls[idx_munmap];
 
       if (__builtin_expect (result == 0, 1))
 	{
 	  /* Keep track of total memory freed using `free'.  */
-	  atomic_add (&total[idx_munmap], len);
+	  total[idx_munmap] += len;
 
 	  /* Update the allocation data and write out the records if
 	     necessary.  */
 	  update_data (NULL, 0, len);
 	}
       else
-	atomic_increment (&failed[idx_munmap]);
+	++failed[idx_munmap];
     }
 
   return result;
@@ -789,12 +745,7 @@ dest (void)
   if (fd != -1)
     {
       /* Write the partially filled buffer.  */
-      if (buffer_cnt > buffer_size)
-	write (fd, buffer + buffer_size,
-	       (buffer_cnt - buffer_size) * sizeof (struct entry));
-      else
-	write (fd, buffer, buffer_cnt * sizeof (struct entry));
-
+      write (fd, buffer, buffer_cnt * sizeof (struct entry));
       /* Go back to the beginning of the file.  We allocated two records
 	 here when we opened the file.  */
       lseek (fd, 0, SEEK_SET);
@@ -818,58 +769,38 @@ dest (void)
 \e[01;32mMemory usage summary:\e[0;0m heap total: %llu, heap peak: %lu, stack peak: %lu\n\
 \e[04;34m         total calls   total memory   failed calls\e[0m\n\
 \e[00;34m malloc|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n\
-\e[00;34mrealloc|\e[0m %10lu   %12llu   %s%12lu\e[00;00m  (nomove:%ld, dec:%ld, free:%ld)\n\
+\e[00;34mrealloc|\e[0m %10lu   %12llu   %s%12lu\e[00;00m   (in place: %ld, dec: %ld)\n\
 \e[00;34m calloc|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n\
 \e[00;34m   free|\e[0m %10lu   %12llu\n",
-	   (unsigned long long int) grand_total, (unsigned long int) peak_heap,
+	   grand_total, (unsigned long int) peak_heap,
 	   (unsigned long int) peak_stack,
-	   (unsigned long int) calls[idx_malloc],
-	   (unsigned long long int) total[idx_malloc],
-	   failed[idx_malloc] ? "\e[01;41m" : "",
-	   (unsigned long int) failed[idx_malloc],
-	   (unsigned long int) calls[idx_realloc],
-	   (unsigned long long int) total[idx_realloc],
-	   failed[idx_realloc] ? "\e[01;41m" : "",
-	   (unsigned long int) failed[idx_realloc],
-	   (unsigned long int) inplace,
-	   (unsigned long int) decreasing,
-	   (unsigned long int) realloc_free,
-	   (unsigned long int) calls[idx_calloc],
-	   (unsigned long long int) total[idx_calloc],
-	   failed[idx_calloc] ? "\e[01;41m" : "",
-	   (unsigned long int) failed[idx_calloc],
-	   (unsigned long int) calls[idx_free],
-	   (unsigned long long int) total[idx_free]);
+	   calls[idx_malloc], total[idx_malloc],
+	   failed[idx_malloc] ? "\e[01;41m" : "", failed[idx_malloc],
+	   calls[idx_realloc], total[idx_realloc],
+	   failed[idx_realloc] ? "\e[01;41m" : "", failed[idx_realloc],
+	   inplace, decreasing,
+	   calls[idx_calloc], total[idx_calloc],
+	   failed[idx_calloc] ? "\e[01;41m" : "", failed[idx_calloc],
+	   calls[idx_free], total[idx_free]);
 
   if (trace_mmap)
     fprintf (stderr, "\
 \e[00;34mmmap(r)|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n\
 \e[00;34mmmap(w)|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n\
 \e[00;34mmmap(a)|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n\
-\e[00;34m mremap|\e[0m %10lu   %12llu   %s%12lu\e[00;00m  (nomove: %ld, dec:%ld)\n\
+\e[00;34m mremap|\e[0m %10lu   %12llu   %s%12lu\e[00;00m   (in place: %ld, dec: %ld)\n\
 \e[00;34m munmap|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n",
-	     (unsigned long int) calls[idx_mmap_r],
-	     (unsigned long long int) total[idx_mmap_r],
-	     failed[idx_mmap_r] ? "\e[01;41m" : "",
-	     (unsigned long int) failed[idx_mmap_r],
-	     (unsigned long int) calls[idx_mmap_w],
-	     (unsigned long long int) total[idx_mmap_w],
-	     failed[idx_mmap_w] ? "\e[01;41m" : "",
-	     (unsigned long int) failed[idx_mmap_w],
-	     (unsigned long int) calls[idx_mmap_a],
-	     (unsigned long long int) total[idx_mmap_a],
-	     failed[idx_mmap_a] ? "\e[01;41m" : "",
-	     (unsigned long int) failed[idx_mmap_a],
-	     (unsigned long int) calls[idx_mremap],
-	     (unsigned long long int) total[idx_mremap],
-	     failed[idx_mremap] ? "\e[01;41m" : "",
-	     (unsigned long int) failed[idx_mremap],
-	     (unsigned long int) inplace_mremap,
-	     (unsigned long int) decreasing_mremap,
-	     (unsigned long int) calls[idx_munmap],
-	     (unsigned long long int) total[idx_munmap],
-	     failed[idx_munmap] ? "\e[01;41m" : "",
-	     (unsigned long int) failed[idx_munmap]);
+	     calls[idx_mmap_r], total[idx_mmap_r],
+	     failed[idx_mmap_r] ? "\e[01;41m" : "", failed[idx_mmap_r],
+	     calls[idx_mmap_w], total[idx_mmap_w],
+	     failed[idx_mmap_w] ? "\e[01;41m" : "", failed[idx_mmap_w],
+	     calls[idx_mmap_a], total[idx_mmap_a],
+	     failed[idx_mmap_a] ? "\e[01;41m" : "", failed[idx_mmap_a],
+	     calls[idx_mremap], total[idx_mremap],
+	     failed[idx_mremap] ? "\e[01;41m" : "", failed[idx_mremap],
+	     inplace_mremap, decreasing_mremap,
+	     calls[idx_munmap], total[idx_munmap],
+	     failed[idx_munmap] ? "\e[01;41m" : "", failed[idx_munmap]);
 
   /* Write out a histoogram of the sizes of the allocations.  */
   fprintf (stderr, "\e[01;32mHistogram for block sizes:\e[0;0m\n");
@@ -886,7 +817,7 @@ dest (void)
       {
 	percent = (histogram[cnt / 16] * 100) / calls_total;
 	fprintf (stderr, "%5d-%-5d%12lu ", cnt, cnt + 15,
-		 (unsigned long int) histogram[cnt / 16]);
+		 histogram[cnt / 16]);
 	if (percent == 0)
 	  fputs (" <1% \e[41;37m", stderr);
 	else
@@ -903,7 +834,7 @@ dest (void)
   if (large != 0)
     {
       percent = (large * 100) / calls_total;
-      fprintf (stderr, "   large   %12lu ", (unsigned long int) large);
+      fprintf (stderr, "   large   %12lu ", large);
       if (percent == 0)
 	fputs (" <1% \e[41;37m", stderr);
       else
@@ -913,10 +844,4 @@ dest (void)
         fputc ('=', stderr);
       fputs ("\e[0;0m\n", stderr);
     }
-
-  /* Any following malloc/free etc. calls should generate statistics again,
-     because otherwise freeing something that has been malloced before
-     this destructor (including struct header in front of it) wouldn't
-     be properly freed.  */
-  not_me = false;
 }
diff --git a/malloc/memusage.sh b/malloc/memusage.sh
index 47f8cc22ff..be8f755a20 100755
--- a/malloc/memusage.sh
+++ b/malloc/memusage.sh
@@ -1,5 +1,5 @@
 #! @BASH@
-# Copyright (C) 1999-2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+# Copyright (C) 1999,2000,2001,2002,2003,2004 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@gnu.org>, 1999.
 
@@ -18,8 +18,8 @@
 # Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
 # 02111-1307 USA.
 
-memusageso='@SLIBDIR@/libmemusage.so'
-memusagestat='@BINDIR@/memusagestat'
+memusageso=@SLIBDIR@/libmemusage.so
+memusagestat=@BINDIR@/memusagestat
 TEXTDOMAIN=libc
 
 # Print usage message.
@@ -71,21 +71,12 @@ do_version() {
   printf $"Copyright (C) %s Free Software Foundation, Inc.
 This is free software; see the source for copying conditions.  There is NO
 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-" "2006"
+" "2004"
   printf $"Written by %s.
 " "Ulrich Drepper"
   exit 0
 }
 
-# These variables are local
-buffer=
-data=
-memusagestat_args=
-notimer=
-png=
-progname=
-tracemmap=
-
 # Process arguments.  But stop as soon as the program name is found.
 while test $# -gt 0; do
   case "$1" in
@@ -222,8 +213,15 @@ datafile=
 if test -n "$data"; then
   datafile="$data"
 elif test -n "$png"; then
-  datafile=$(mktemp -t memusage.XXXXXX) || exit
-  trap 'rm -f "$datafile"; exit 1' HUP INT QUIT TERM PIPE
+  datafile=$(mktemp ${TMPDIR:-/tmp}/memusage.XXXXXX 2> /dev/null)
+  if test $? -ne 0; then
+    # Lame, but if there is no `mktemp' program the user cannot expect more.
+    if test "$RANDOM" != "$RANDOM"; then
+      datafile=${TMPDIR:-/tmp}/memusage.$RANDOM
+    else
+      datafile=${TMPDIR:-/tmp}/memusage.$$
+    fi
+  fi
 fi
 if test -n "$datafile"; then
   add_env="$add_env MEMUSAGE_OUTPUT=$datafile"
diff --git a/malloc/memusagestat.c b/malloc/memusagestat.c
index 8a74ec8dcf..b1cad9b251 100644
--- a/malloc/memusagestat.c
+++ b/malloc/memusagestat.c
@@ -1,20 +1,22 @@
 /* Generate graphic from memory profiling data.
-   Copyright (C) 1998, 1999, 2000, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc.
    This file is part of the GNU C Library.
    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1998.
 
-   This program is free software; you can redistribute it and/or modify
-   it under the terms of the GNU General Public License version 2 as
-   published by the Free Software Foundation.
+   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.
 
-   This program is distributed in the hope that it will be useful,
+   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 General Public License for more details.
+   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 General Public License
-   along with this program; if not, write to the Free Software Foundation,
-   Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
+   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.  */
 
 #define _FILE_OFFSET_BITS 64
 
@@ -81,8 +83,8 @@ static struct argp argp =
 
 struct entry
 {
-  uint64_t heap;
-  uint64_t stack;
+  size_t heap;
+  size_t stack;
   uint32_t time_low;
   uint32_t time_high;
 };
@@ -277,16 +279,16 @@ main (int argc, char *argv[])
 
   gdImageString (im_out, gdFontSmall, 38, ysize - 14, (unsigned char *) "0",
 		 blue);
-  snprintf (buf, sizeof (buf), heap_format, 0);
+  snprintf(buf, sizeof (buf), heap_format, 0);
   gdImageString (im_out, gdFontSmall, maxsize_heap < 1024 ? 32 : 26,
-		 ysize - 26, (unsigned char *) buf, red);
-  snprintf (buf, sizeof (buf), stack_format, 0);
+		 ysize - 26, buf, red);
+  snprintf(buf, sizeof (buf), stack_format, 0);
   gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26,
-		 (unsigned char *) buf, green);
+		 buf, green);
 
   if (string != NULL)
     gdImageString (im_out, gdFontLarge, (xsize - strlen (string) * 8) / 2,
-		   2, (unsigned char *) string, green);
+		   2, (char *) string, green);
 
   gdImageStringUp (im_out, gdFontSmall, 1, ysize / 2 - 10,
 		   (unsigned char *) "allocated", red);
@@ -299,11 +301,9 @@ main (int argc, char *argv[])
 		   (unsigned char *) "stack", green);
 
   snprintf (buf, sizeof (buf), heap_format, maxsize_heap / heap_scale);
-  gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, 14,
-		 (unsigned char *) buf, red);
+  gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6, 14, buf, red);
   snprintf (buf, sizeof (buf), stack_format, maxsize_stack / stack_scale);
-  gdImageString (im_out, gdFontSmall, xsize - 37, 14,
-		 (unsigned char *) buf, green);
+  gdImageString (im_out, gdFontSmall, xsize - 37, 14, buf, green);
 
   for (line = 1; line <= 3; ++line)
     {
@@ -311,10 +311,10 @@ main (int argc, char *argv[])
 	(maxsize_heap / heap_scale);
       gdImageDashedLine (im_out, 40, ysize - 20 - cnt, xsize - 40,
 			 ysize - 20 - cnt, red);
-      snprintf (buf, sizeof (buf), heap_format, maxsize_heap / 4 * line /
+      snprintf (buf, sizeof (buf), heap_format, maxsize_heap / 4 * line / 
 		heap_scale);
       gdImageString (im_out, gdFontSmall, 39 - strlen (buf) * 6,
-		     ysize - 26 - cnt, (unsigned char *) buf, red);
+		     ysize - 26 - cnt, buf, red);
 
       cnt2 = ((ysize - 40) * (maxsize_stack / 4 * line / stack_scale)) /
 	(maxsize_stack / stack_scale);
@@ -324,12 +324,11 @@ main (int argc, char *argv[])
       snprintf (buf, sizeof (buf), stack_format, maxsize_stack / 4 * line /
 		stack_scale);
       gdImageString (im_out, gdFontSmall, xsize - 37, ysize - 26 - cnt2,
-		     (unsigned char *) buf, green);
+		     buf, green);
     }
 
   snprintf (buf, sizeof (buf), "%llu", (unsigned long long) total);
-  gdImageString (im_out, gdFontSmall, xsize - 50, ysize - 14,
-		 (unsigned char *) buf, blue);
+  gdImageString (im_out, gdFontSmall, xsize - 50, ysize - 14, buf, blue);
 
   if (!time_based)
     {
diff --git a/malloc/morecore.c b/malloc/morecore.c
deleted file mode 100644
index 0a66ef5a85..0000000000
--- a/malloc/morecore.c
+++ /dev/null
@@ -1,54 +0,0 @@
-/* Copyright (C) 1991,92,93,94,95,97,2002,2004 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	_MALLOC_INTERNAL
-#define	_MALLOC_INTERNAL
-#include <malloc.h>
-#endif
-
-#ifndef	__GNU_LIBRARY__
-#define	__sbrk	sbrk
-#endif
-
-#ifdef __GNU_LIBRARY__
-/* It is best not to declare this and cast its result on foreign operating
-   systems with potentially hostile include files.  */
-
-#include <stddef.h>
-#include <stdlib.h>
-extern __malloc_ptr_t __sbrk (ptrdiff_t increment) __THROW;
-libc_hidden_proto (__sbrk)
-#endif
-
-#ifndef NULL
-#define NULL 0
-#endif
-
-/* Allocate INCREMENT more bytes of data space,
-   and return the start of data space, or NULL on errors.
-   If INCREMENT is negative, shrink data space.  */
-__malloc_ptr_t
-__default_morecore (increment)
-     __malloc_ptrdiff_t increment;
-{
-  __malloc_ptr_t result = (__malloc_ptr_t) __sbrk (increment);
-  if (result == (__malloc_ptr_t) -1)
-    return NULL;
-  return result;
-}
-libc_hidden_def (__default_morecore)
diff --git a/malloc/mtrace.c b/malloc/mtrace.c
index 139ebc8153..1a9522b09d 100644
--- a/malloc/mtrace.c
+++ b/malloc/mtrace.c
@@ -40,18 +40,6 @@
 # include <libio/iolibio.h>
 # define setvbuf(s, b, f, l) INTUSE(_IO_setvbuf) (s, b, f, l)
 # define fwrite(buf, size, count, fp) _IO_fwrite (buf, size, count, fp)
-extern __typeof (malloc) __libc_malloc;
-extern __typeof (free) __libc_free;
-extern __typeof (realloc) __libc_realloc;
-libc_hidden_proto (__libc_malloc)
-libc_hidden_proto (__libc_realloc)
-libc_hidden_proto (__libc_free)
-libc_hidden_proto (__libc_memalign)
-#else
-# define __libc_malloc(sz) malloc (sz)
-# define __libc_free(ptr) free (ptr)
-# define __libc_realloc(ptr, sz) realloc (ptr, sz)
-# define __libc_memalign(al, sz) memalign (al, sz)
 #endif
 
 #ifndef attribute_hidden
@@ -166,7 +154,7 @@ tr_freehook (ptr, caller)
   if (tr_old_free_hook != NULL)
     (*tr_old_free_hook) (ptr, caller);
   else
-    __libc_free (ptr);
+    free (ptr);
   __free_hook = tr_freehook;
   __libc_lock_unlock (lock);
 }
@@ -185,7 +173,7 @@ tr_mallochook (size, caller)
   if (tr_old_malloc_hook != NULL)
     hdr = (__ptr_t) (*tr_old_malloc_hook) (size, caller);
   else
-    hdr = (__ptr_t) __libc_malloc (size);
+    hdr = (__ptr_t) malloc (size);
   __malloc_hook = tr_mallochook;
 
   tr_where (caller);
@@ -221,7 +209,7 @@ tr_reallochook (ptr, size, caller)
   if (tr_old_realloc_hook != NULL)
     hdr = (__ptr_t) (*tr_old_realloc_hook) (ptr, size, caller);
   else
-    hdr = (__ptr_t) __libc_realloc (ptr, size);
+    hdr = (__ptr_t) realloc (ptr, size);
   __free_hook = tr_freehook;
   __malloc_hook = tr_mallochook;
   __realloc_hook = tr_reallochook;
@@ -263,7 +251,7 @@ tr_memalignhook (alignment, size, caller)
   if (tr_old_memalign_hook != NULL)
     hdr = (__ptr_t) (*tr_old_memalign_hook) (alignment, size, caller);
   else
-    hdr = (__ptr_t) __libc_memalign (alignment, size);
+    hdr = (__ptr_t) memalign (alignment, size);
   __memalign_hook = tr_memalignhook;
   __malloc_hook = tr_mallochook;
 
diff --git a/malloc/mtrace.pl b/malloc/mtrace.pl
index 8a0fbc7e95..1640fa652d 100644
--- a/malloc/mtrace.pl
+++ b/malloc/mtrace.pl
@@ -1,7 +1,7 @@
 #! @PERL@
 eval "exec @PERL@ -S $0 $*"
     if 0;
-# Copyright (C) 1997-2004, 2005, 2006 Free Software Foundation, Inc.
+# Copyright (C) 1997-2002, 2003, 2004 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 # Contributed by Ulrich Drepper <drepper@gnu.org>, 1997.
 # Based on the mtrace.awk script.
@@ -45,7 +45,7 @@ arglist: while (@ARGV) {
 	$ARGV[0] eq "--vers" || $ARGV[0] eq "--versi" ||
 	$ARGV[0] eq "--versio" || $ARGV[0] eq "--version") {
 	print "mtrace (GNU $PACKAGE) $VERSION\n";
-	print "Copyright (C) 2006 Free Software Foundation, Inc.\n";
+	print "Copyright (C) 2004 Free Software Foundation, Inc.\n";
 	print "This is free software; see the source for copying conditions.  There is NO\n";
 	print "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n";
 	print "Written by Ulrich Drepper <drepper\@gnu.org>\n";
diff --git a/malloc/obstack.c b/malloc/obstack.c
index 75440d9c79..fddda3ec5b 100644
--- a/malloc/obstack.c
+++ b/malloc/obstack.c
@@ -1,7 +1,8 @@
 /* obstack.c - subroutines used implicitly by object stack macros
-   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997, 1998,
-   1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+   Copyright (C) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1996, 1997,
+   1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -15,9 +16,8 @@
 
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
-
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 #ifdef HAVE_CONFIG_H
 # include <config.h>
@@ -52,38 +52,22 @@
 # endif
 #endif
 
-#include <stddef.h>
+#if defined _LIBC && defined USE_IN_LIBIO
+# include <wchar.h>
+#endif
 
 #ifndef ELIDE_CODE
 
 
-# if HAVE_INTTYPES_H
-#  include <inttypes.h>
-# endif
-# if HAVE_STDINT_H || defined _LIBC
-#  include <stdint.h>
-# endif
-
 /* Determine default alignment.  */
-union fooround
-{
-  uintmax_t i;
-  long double d;
-  void *p;
-};
-struct fooalign
-{
-  char c;
-  union fooround u;
-};
+struct fooalign {char x; double d;};
+# define DEFAULT_ALIGNMENT  \
+  ((PTR_INT_TYPE) ((char *) &((struct fooalign *) 0)->d - (char *) 0))
 /* If malloc were really smart, it would round addresses to DEFAULT_ALIGNMENT.
    But in fact it might be less smart and round addresses to as much as
    DEFAULT_ROUNDING.  So we prepare for it to do that.  */
-enum
-  {
-    DEFAULT_ALIGNMENT = offsetof (struct fooalign, u),
-    DEFAULT_ROUNDING = sizeof (union fooround)
-  };
+union fooround {long x; double d;};
+# define DEFAULT_ROUNDING (sizeof (union fooround))
 
 /* When we copy a long block of data, this is the unit to do it with.
    On some machines, copying successive ints does not work;
@@ -159,7 +143,7 @@ _obstack_begin (struct obstack *h,
   register struct _obstack_chunk *chunk; /* points to new chunk */
 
   if (alignment == 0)
-    alignment = DEFAULT_ALIGNMENT;
+    alignment = (int) DEFAULT_ALIGNMENT;
   if (size == 0)
     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     {
@@ -186,8 +170,7 @@ _obstack_begin (struct obstack *h,
   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
   if (!chunk)
     (*obstack_alloc_failed_handler) ();
-  h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
-					       alignment - 1);
+  h->next_free = h->object_base = chunk->contents;
   h->chunk_limit = chunk->limit
     = (char *) chunk + h->chunk_size;
   chunk->prev = 0;
@@ -206,7 +189,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
   register struct _obstack_chunk *chunk; /* points to new chunk */
 
   if (alignment == 0)
-    alignment = DEFAULT_ALIGNMENT;
+    alignment = (int) DEFAULT_ALIGNMENT;
   if (size == 0)
     /* Default size is what GNU malloc can fit in a 4096-byte block.  */
     {
@@ -234,8 +217,7 @@ _obstack_begin_1 (struct obstack *h, int size, int alignment,
   chunk = h->chunk = CALL_CHUNKFUN (h, h -> chunk_size);
   if (!chunk)
     (*obstack_alloc_failed_handler) ();
-  h->next_free = h->object_base = __PTR_ALIGN ((char *) chunk, chunk->contents,
-					       alignment - 1);
+  h->next_free = h->object_base = chunk->contents;
   h->chunk_limit = chunk->limit
     = (char *) chunk + h->chunk_size;
   chunk->prev = 0;
@@ -277,7 +259,8 @@ _obstack_newchunk (struct obstack *h, int length)
 
   /* Compute an aligned object_base in the new chunk */
   object_base =
-    __PTR_ALIGN ((char *) new_chunk, new_chunk->contents, h->alignment_mask);
+    __INT_TO_PTR ((__PTR_TO_INT (new_chunk->contents) + h->alignment_mask)
+		  & ~ (h->alignment_mask));
 
   /* Move the existing object to the new chunk.
      Word at a time is fast and is safe if the object
@@ -302,10 +285,7 @@ _obstack_newchunk (struct obstack *h, int length)
   /* If the object just copied was the only data in OLD_CHUNK,
      free that chunk and remove it from the chain.
      But not if that chunk might contain an empty object.  */
-  if (! h->maybe_empty_object
-      && (h->object_base
-	  == __PTR_ALIGN ((char *) old_chunk, old_chunk->contents,
-			  h->alignment_mask)))
+  if (h->object_base == old_chunk->contents && ! h->maybe_empty_object)
     {
       new_chunk->prev = old_chunk->prev;
       CALL_FREEFUN (h, old_chunk);
@@ -430,11 +410,12 @@ print_and_abort (void)
      happen because the "memory exhausted" message appears in other places
      like this and the translation should be reused instead of creating
      a very similar string which requires a separate translation.  */
-# ifdef _LIBC
-  (void) __fxprintf (NULL, "%s\n", _("memory exhausted"));
-# else
-  fprintf (stderr, "%s\n", _("memory exhausted"));
+# if defined _LIBC && defined USE_IN_LIBIO
+  if (_IO_fwide (stderr, 0) > 0)
+    __fwprintf (stderr, L"%s\n", _("memory exhausted"));
+  else
 # endif
+    fprintf (stderr, "%s\n", _("memory exhausted"));
   exit (obstack_exit_failure);
 }
 
diff --git a/malloc/obstack.h b/malloc/obstack.h
index 206fe55050..d18ef40b6e 100644
--- a/malloc/obstack.h
+++ b/malloc/obstack.h
@@ -1,7 +1,7 @@
 /* obstack.h - object stack macros
-   Copyright (C) 1988-1994,1996-1999,2003,2004,2005
-	Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
+   Copyright (C) 1988-1994,1996-1999,2003,2004 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.  Its master source is NOT part of
+   the C library, however.  The master source lives in /gd/gnu/lib.
 
    The GNU C Library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -15,8 +15,8 @@
 
    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., 51 Franklin Street, Fifth Floor,
-   Boston, MA 02110-1301, USA.  */
+   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   02111-1307 USA.  */
 
 /* Summary:
 
@@ -110,7 +110,19 @@ Summary:
 extern "C" {
 #endif
 
-/* We need the type of a pointer subtraction.  If __PTRDIFF_TYPE__ is
+/* We use subtraction of (char *) 0 instead of casting to int
+   because on word-addressable machines a simple cast to int
+   may ignore the byte-within-word field of the pointer.  */
+
+#ifndef __PTR_TO_INT
+# define __PTR_TO_INT(P) ((P) - (char *) 0)
+#endif
+
+#ifndef __INT_TO_PTR
+# define __INT_TO_PTR(P) ((P) + (char *) 0)
+#endif
+
+/* We need the type of the resulting object.  If __PTRDIFF_TYPE__ is
    defined, as with GNU C, use that; that way we don't pollute the
    namespace with <stddef.h>'s symbols.  Otherwise, include <stddef.h>
    and use ptrdiff_t.  */
@@ -122,23 +134,6 @@ extern "C" {
 # define PTR_INT_TYPE ptrdiff_t
 #endif
 
-/* If B is the base of an object addressed by P, return the result of
-   aligning P to the next multiple of A + 1.  B and P must be of type
-   char *.  A + 1 must be a power of 2.  */
-
-#define __BPTR_ALIGN(B, P, A) ((B) + (((P) - (B) + (A)) & ~(A)))
-
-/* Similiar to _BPTR_ALIGN (B, P, A), except optimize the common case
-   where pointers can be converted to integers, aligned as integers,
-   and converted back again.  If PTR_INT_TYPE is narrower than a
-   pointer (e.g., the AS/400), play it safe and compute the alignment
-   relative to B.  Otherwise, use the faster strategy of computing the
-   alignment relative to 0.  */
-
-#define __PTR_ALIGN(B, P, A)						    \
-  __BPTR_ALIGN (sizeof (PTR_INT_TYPE) < sizeof (void *) ? (B) : (char *) 0, \
-		P, A)
-
 #include <string.h>
 
 struct _obstack_chunk		/* Lives at front of each chunk. */
@@ -155,11 +150,7 @@ struct obstack		/* control current object in current chunk */
   char	*object_base;		/* address of object we are building */
   char	*next_free;		/* where to add next char to current object */
   char	*chunk_limit;		/* address of char after current chunk */
-  union
-  {
-    PTR_INT_TYPE tempint;
-    void *tempptr;
-  } temp;			/* Temporary for some macros.  */
+  PTR_INT_TYPE temp;		/* Temporary for some macros.  */
   int   alignment_mask;		/* Mask of alignment for each object. */
   /* These prototypes vary based on `use_extra_arg', and we use
      casts to the prototypeless function type in all assignments,
@@ -284,10 +275,7 @@ __extension__								\
 # define obstack_empty_p(OBSTACK)					\
   __extension__								\
   ({ struct obstack const *__o = (OBSTACK);				\
-     (__o->chunk->prev == 0						\
-      && __o->next_free == __PTR_ALIGN ((char *) __o->chunk,		\
-					__o->chunk->contents,		\
-					__o->alignment_mask)); })
+     (__o->chunk->prev == 0 && __o->next_free - __o->chunk->contents == 0); })
 
 # define obstack_grow(OBSTACK,where,length)				\
 __extension__								\
@@ -386,8 +374,8 @@ __extension__								\
    if (__o1->next_free == __value)					\
      __o1->maybe_empty_object = 1;					\
    __o1->next_free							\
-     = __PTR_ALIGN (__o1->object_base, __o1->next_free,			\
-		    __o1->alignment_mask);				\
+     = __INT_TO_PTR ((__PTR_TO_INT (__o1->next_free)+__o1->alignment_mask)\
+		     & ~ (__o1->alignment_mask));			\
    if (__o1->next_free - (char *)__o1->chunk				\
        > __o1->chunk_limit - (char *)__o1->chunk)			\
      __o1->next_free = __o1->chunk_limit;				\
@@ -411,10 +399,7 @@ __extension__								\
  (unsigned) ((h)->chunk_limit - (h)->next_free)
 
 # define obstack_empty_p(h) \
- ((h)->chunk->prev == 0							\
-  && (h)->next_free == __PTR_ALIGN ((char *) (h)->chunk,		\
-				    (h)->chunk->contents,		\
-				    (h)->alignment_mask))
+ ((h)->chunk->prev == 0 && (h)->next_free - (h)->chunk->contents == 0)
 
 /* Note that the call to _obstack_newchunk is enclosed in (..., 0)
    so that we can avoid having void expressions
@@ -423,23 +408,23 @@ __extension__								\
    but some compilers won't accept it.  */
 
 # define obstack_make_room(h,length)					\
-( (h)->temp.tempint = (length),						\
-  (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit)		\
-   ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0))
+( (h)->temp = (length),							\
+  (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
+   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0))
 
 # define obstack_grow(h,where,length)					\
-( (h)->temp.tempint = (length),						\
-  (((h)->next_free + (h)->temp.tempint > (h)->chunk_limit)		\
-   ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0),		\
-  memcpy ((h)->next_free, where, (h)->temp.tempint),			\
-  (h)->next_free += (h)->temp.tempint)
+( (h)->temp = (length),							\
+  (((h)->next_free + (h)->temp > (h)->chunk_limit)			\
+   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
+  memcpy ((h)->next_free, where, (h)->temp),				\
+  (h)->next_free += (h)->temp)
 
 # define obstack_grow0(h,where,length)					\
-( (h)->temp.tempint = (length),						\
-  (((h)->next_free + (h)->temp.tempint + 1 > (h)->chunk_limit)		\
-   ? (_obstack_newchunk ((h), (h)->temp.tempint + 1), 0) : 0),		\
-  memcpy ((h)->next_free, where, (h)->temp.tempint),			\
-  (h)->next_free += (h)->temp.tempint,					\
+( (h)->temp = (length),							\
+  (((h)->next_free + (h)->temp + 1 > (h)->chunk_limit)			\
+   ? (_obstack_newchunk ((h), (h)->temp + 1), 0) : 0),			\
+  memcpy ((h)->next_free, where, (h)->temp),				\
+  (h)->next_free += (h)->temp,						\
   *((h)->next_free)++ = 0)
 
 # define obstack_1grow(h,datum)						\
@@ -461,13 +446,13 @@ __extension__								\
   (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
 
 # define obstack_int_grow_fast(h,aint)					\
-  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
+  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
 
 # define obstack_blank(h,length)					\
-( (h)->temp.tempint = (length),						\
-  (((h)->chunk_limit - (h)->next_free < (h)->temp.tempint)		\
-   ? (_obstack_newchunk ((h), (h)->temp.tempint), 0) : 0),		\
-  obstack_blank_fast (h, (h)->temp.tempint))
+( (h)->temp = (length),							\
+  (((h)->chunk_limit - (h)->next_free < (h)->temp)			\
+   ? (_obstack_newchunk ((h), (h)->temp), 0) : 0),			\
+  obstack_blank_fast (h, (h)->temp))
 
 # define obstack_alloc(h,length)					\
  (obstack_blank ((h), (length)), obstack_finish ((h)))
@@ -482,23 +467,22 @@ __extension__								\
 ( ((h)->next_free == (h)->object_base					\
    ? (((h)->maybe_empty_object = 1), 0)					\
    : 0),								\
-  (h)->temp.tempptr = (h)->object_base,					\
+  (h)->temp = __PTR_TO_INT ((h)->object_base),				\
   (h)->next_free							\
-    = __PTR_ALIGN ((h)->object_base, (h)->next_free,			\
-		   (h)->alignment_mask),				\
+    = __INT_TO_PTR ((__PTR_TO_INT ((h)->next_free)+(h)->alignment_mask)	\
+		    & ~ ((h)->alignment_mask)),				\
   (((h)->next_free - (char *) (h)->chunk				\
     > (h)->chunk_limit - (char *) (h)->chunk)				\
    ? ((h)->next_free = (h)->chunk_limit) : 0),				\
   (h)->object_base = (h)->next_free,					\
-  (h)->temp.tempptr)
+  (void *) __INT_TO_PTR ((h)->temp))
 
 # define obstack_free(h,obj)						\
-( (h)->temp.tempint = (char *) (obj) - (char *) (h)->chunk,		\
-  ((((h)->temp.tempint > 0						\
-    && (h)->temp.tempint < (h)->chunk_limit - (char *) (h)->chunk))	\
+( (h)->temp = (char *) (obj) - (char *) (h)->chunk,			\
+  (((h)->temp > 0 && (h)->temp < (h)->chunk_limit - (char *) (h)->chunk)\
    ? (int) ((h)->next_free = (h)->object_base				\
-	    = (h)->temp.tempint + (char *) (h)->chunk)			\
-   : (((obstack_free) ((h), (h)->temp.tempint + (char *) (h)->chunk), 0), 0)))
+	    = (h)->temp + (char *) (h)->chunk)				\
+   : (((obstack_free) ((h), (h)->temp + (char *) (h)->chunk), 0), 0)))
 
 #endif /* not __GNUC__ or not __STDC__ */
 
diff --git a/malloc/tst-malloc.c b/malloc/tst-malloc.c
index 81d279236c..d555ae46ef 100644
--- a/malloc/tst-malloc.c
+++ b/malloc/tst-malloc.c
@@ -33,7 +33,7 @@ merror (const char *msg)
 int
 main (void)
 {
-  void *p, *q;
+  void *p;
   int save;
 
   errno = 0;
@@ -64,15 +64,5 @@ main (void)
   if (p != NULL)
     merror ("realloc (p, 0) failed.");
 
-  p = malloc (513 * 1024);
-  if (p == NULL)
-    merror ("malloc (513K) failed.");
-
-  q = malloc (-512 * 1024);
-  if (q != NULL)
-    merror ("malloc (-512K) succeeded.");
-
-  free (p);
-
   return errors != 0;
 }
diff --git a/malloc/tst-mallocfork.c b/malloc/tst-mallocfork.c
deleted file mode 100644
index f90ce94887..0000000000
--- a/malloc/tst-mallocfork.c
+++ /dev/null
@@ -1,51 +0,0 @@
-/* Derived from the test case in
-   http://sourceware.org/bugzilla/show_bug.cgi?id=838.  */
-#include <assert.h>
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <sys/types.h>
-#include <sys/wait.h>
-
-static void
-sig_handler (int signum)
-{
-  pid_t child = fork ();
-  if (child == 0)
-    exit (0);
-  TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
-}
-
-static int
-do_test (void)
-{
-  pid_t parent = getpid ();
-
-  struct sigaction action = { .sa_handler = sig_handler };
-  sigemptyset (&action.sa_mask);
-
-  malloc (sizeof (int));
-
-  if (sigaction (SIGALRM, &action, NULL) != 0)
-    {
-      puts ("sigaction failed");
-      return 1;
-    }
-
-  /* Create a child that sends the signal to be caught.  */
-  pid_t child = fork ();
-  if (child == 0)
-    {
-      if (kill (parent, SIGALRM) == -1)
-	perror ("kill");
-      exit (0);
-    }
-
-  TEMP_FAILURE_RETRY (waitpid (child, NULL, 0));
-
-  return 0;
-}
-
-#define TEST_FUNCTION do_test ()
-#include "../test-skeleton.c"
diff --git a/malloc/tst-mcheck.c b/malloc/tst-mcheck.c
deleted file mode 100644
index 16784912a9..0000000000
--- a/malloc/tst-mcheck.c
+++ /dev/null
@@ -1,91 +0,0 @@
-/* Copyright (C) 2005 Free Software Foundation, Inc.
-   This file is part of the GNU C Library.
-   Contributed by Jakub Jelinek <jakub@redhat.com>, 2005.
-
-   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 <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-static int errors = 0;
-
-static void
-merror (const char *msg)
-{
-  ++errors;
-  printf ("Error: %s\n", msg);
-}
-
-int
-main (void)
-{
-  void *p, *q;
-
-  errno = 0;
-
-  p = malloc (-1);
-
-  if (p != NULL)
-    merror ("malloc (-1) succeeded.");
-  else if (errno != ENOMEM)
-    merror ("errno is not set correctly.");
-
-  p = malloc (10);
-  if (p == NULL)
-    merror ("malloc (10) failed.");
-
-  p = realloc (p, 0);
-  if (p != NULL)
-    merror ("realloc (p, 0) failed.");
-
-  p = malloc (0);
-  if (p == NULL)
-    merror ("malloc (0) failed.");
-
-  p = realloc (p, 0);
-  if (p != NULL)
-    merror ("realloc (p, 0) failed.");
-
-  q = malloc (256);
-  if (q == NULL)
-    merror ("malloc (256) failed.");
-
-  p = malloc (512);
-  if (p == NULL)
-    merror ("malloc (512) failed.");
-
-  if (realloc (p, -256) != NULL)
-    merror ("realloc (p, -256) succeeded.");
-  else if (errno != ENOMEM)
-    merror ("errno is not set correctly.");
-
-  free (p);
-
-  p = malloc (512);
-  if (p == NULL)
-    merror ("malloc (512) failed.");
-
-  if (realloc (p, -1) != NULL)
-    merror ("realloc (p, -1) succeeded.");
-  else if (errno != ENOMEM)
-    merror ("errno is not set correctly.");
-
-  free (p);
-  free (q);
-
-  return errors != 0;
-}
diff --git a/malloc/tst-mtrace.sh b/malloc/tst-mtrace.sh
index 771689a273..d4fee2a357 100755
--- a/malloc/tst-mtrace.sh
+++ b/malloc/tst-mtrace.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Testing the mtrace function.
-# Copyright (C) 2000, 2005 Free Software Foundation, Inc.
+# Copyright (C) 2000 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 #
 
@@ -30,7 +30,8 @@ ${common_objpfx}elf/ld.so --library-path $common_objpfx \
   ${common_objpfx}malloc/tst-mtrace || status=1
 
 if test $status -eq 0 && test -f ${common_objpfx}malloc/mtrace; then
-  ${common_objpfx}malloc/mtrace ${common_objpfx}malloc/tst-mtrace.leak \
+  ${common_objpfx}malloc/mtrace ${common_objpfx}malloc/tst-mtrace \
+    ${common_objpfx}malloc/tst-mtrace.leak \
     > ${common_objpfx}malloc/tst-mtrace.out|| status=1
 fi