about summary refs log tree commit diff
path: root/malloc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-10-20 06:59:57 +0000
committerJakub Jelinek <jakub@redhat.com>2005-10-20 06:59:57 +0000
commitb7071f6fc41f4c20510de3683f39e5c8ea8a2e1e (patch)
tree852f4f1992a3c9ecbb44b822df6702c7e635fc5a /malloc
parentacfebba27b162b3064c616142883541eaef3f725 (diff)
downloadglibc-b7071f6fc41f4c20510de3683f39e5c8ea8a2e1e.tar.gz
glibc-b7071f6fc41f4c20510de3683f39e5c8ea8a2e1e.tar.xz
glibc-b7071f6fc41f4c20510de3683f39e5c8ea8a2e1e.zip
Updated to fedora-glibc-20051020T0651
Diffstat (limited to 'malloc')
-rw-r--r--malloc/arena.c84
-rw-r--r--malloc/hooks.c2
-rw-r--r--malloc/malloc.c57
-rw-r--r--malloc/memusage.c16
-rwxr-xr-xmalloc/tst-mtrace.sh5
5 files changed, 89 insertions, 75 deletions
diff --git a/malloc/arena.c b/malloc/arena.c
index 039d70ff18..abbca1f02e 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -786,6 +786,48 @@ 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
@@ -856,48 +898,6 @@ 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 0f8f274e38..5dd2d65e62 100644
--- a/malloc/hooks.c
+++ b/malloc/hooks.c
@@ -584,7 +584,7 @@ public_sET_STATe(Void_t* msptr)
   (void)mutex_lock(&main_arena.mutex);
   /* There are no fastchunks.  */
   clear_fastchunks(&main_arena);
-  set_max_fast(&main_arena, DEFAULT_MXFAST);
+  set_max_fast(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 594d9c4d7a..4ea35254bb 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -2157,9 +2157,9 @@ typedef struct malloc_chunk* mfastbinptr;
 
 #define FASTCHUNKS_BIT        (1U)
 
-#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)
+#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)
 
 /*
   NONCONTIGUOUS_BIT indicates that MORECORE does not return contiguous
@@ -2172,10 +2172,10 @@ typedef struct malloc_chunk* mfastbinptr;
 
 #define NONCONTIGUOUS_BIT     (2U)
 
-#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)
+#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)
 
 /*
    Set value of max_fast.
@@ -2184,10 +2184,9 @@ typedef struct malloc_chunk* mfastbinptr;
    Setting the value clears fastchunk bit but preserves noncontiguous bit.
 */
 
-#define set_max_fast(M, s) \
-  (M)->max_fast = (((s) == 0)? SMALLBIN_WIDTH: request2size(s)) | \
-  FASTCHUNKS_BIT | \
-  ((M)->max_fast &  NONCONTIGUOUS_BIT)
+#define set_max_fast(s) \
+  global_max_fast = ((s) == 0)? SMALLBIN_WIDTH: request2size(s)
+#define get_max_fast() global_max_fast
 
 
 /*
@@ -2197,16 +2196,15 @@ typedef struct malloc_chunk* mfastbinptr;
 struct malloc_state {
   /* Serialize access.  */
   mutex_t mutex;
-  // Should we have padding to move the mutex to its own cache line?
+
+  /* Flags (formerly in max_fast).  */
+  int flags;
 
 #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];
 
@@ -2267,6 +2265,10 @@ 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.
 
@@ -2296,8 +2298,9 @@ static void malloc_init_state(av) mstate av;
   if (av != &main_arena)
 #endif
     set_noncontiguous(av);
-
-  set_max_fast(av, DEFAULT_MXFAST);
+  if (av == &main_arena)
+    set_max_fast(DEFAULT_MXFAST);
+  av->flags |= FASTCHUNKS_BIT;
 
   av->top            = initial_top(av);
 }
@@ -2639,9 +2642,9 @@ static void do_check_malloc_state(mstate av)
   /* properties of fastbins */
 
   /* max_fast is in allowed range */
-  assert((av->max_fast & ~1) <= request2size(MAX_FAST_SIZE));
+  assert((get_max_fast () & ~1) <= request2size(MAX_FAST_SIZE));
 
-  max_fast_bin = fastbin_index(av->max_fast);
+  max_fast_bin = fastbin_index(get_max_fast ());
 
   for (i = 0; i < NFASTBINS; ++i) {
     p = av->fastbins[i];
@@ -3871,7 +3874,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)(av->max_fast)) {
+  if ((unsigned long)(nb) <= (unsigned long)(get_max_fast ())) {
     long int idx = fastbin_index(nb);
     fb = &(av->fastbins[idx]);
     if ( (victim = *fb) != 0) {
@@ -4275,6 +4278,12 @@ _int_free(mstate av, Void_t* mem)
       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);
 
@@ -4283,7 +4292,7 @@ _int_free(mstate av, Void_t* mem)
     and used quickly in malloc.
   */
 
-  if ((unsigned long)(size) <= (unsigned long)(av->max_fast)
+  if ((unsigned long)(size) <= (unsigned long)(get_max_fast ())
 
 #if TRIM_FASTBINS
       /*
@@ -4499,7 +4508,7 @@ static void malloc_consolidate(av) mstate av;
     yet been initialized, in which case do so below
   */
 
-  if (av->max_fast != 0) {
+  if (get_max_fast () != 0) {
     clear_fastchunks(av);
 
     unsorted_bin = unsorted_chunks(av);
@@ -4512,7 +4521,7 @@ static void malloc_consolidate(av) mstate av;
       reused anyway.
     */
 
-    maxfb = &(av->fastbins[fastbin_index(av->max_fast)]);
+    maxfb = &(av->fastbins[fastbin_index(get_max_fast ())]);
     fb = &(av->fastbins[0]);
     do {
       if ( (p = *fb) != 0) {
@@ -5376,7 +5385,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(av, value);
+      set_max_fast(value);
     }
     else
       res = 0;
diff --git a/malloc/memusage.c b/malloc/memusage.c
index f586ea61ba..8b37c43a8a 100644
--- a/malloc/memusage.c
+++ b/malloc/memusage.c
@@ -24,6 +24,7 @@
 #include <fcntl.h>
 #include <inttypes.h>
 #include <signal.h>
+#include <stdarg.h>
 #include <stdbool.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -44,7 +45,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);
+static void *(*mremapp) (void *, size_t, size_t, int, void *);
 
 enum
 {
@@ -226,8 +227,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)) dlsym (RTLD_NEXT,
-							     "mremap");
+  mremapp = (void *(*) (void *, size_t, size_t, int, void *)) dlsym (RTLD_NEXT,
+								     "mremap");
   munmapp = (int (*) (void *, size_t)) dlsym (RTLD_NEXT, "munmap");
   initialized = 1;
 
@@ -649,9 +650,14 @@ 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))
@@ -662,7 +668,7 @@ 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);
+  result = (*mremapp) (start, old_len, len, flags, newaddr);
 
   if (!not_me && trace_mmap)
     {
diff --git a/malloc/tst-mtrace.sh b/malloc/tst-mtrace.sh
index d4fee2a357..771689a273 100755
--- a/malloc/tst-mtrace.sh
+++ b/malloc/tst-mtrace.sh
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Testing the mtrace function.
-# Copyright (C) 2000 Free Software Foundation, Inc.
+# Copyright (C) 2000, 2005 Free Software Foundation, Inc.
 # This file is part of the GNU C Library.
 #
 
@@ -30,8 +30,7 @@ ${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 \
-    ${common_objpfx}malloc/tst-mtrace.leak \
+  ${common_objpfx}malloc/mtrace ${common_objpfx}malloc/tst-mtrace.leak \
     > ${common_objpfx}malloc/tst-mtrace.out|| status=1
 fi