about summary refs log tree commit diff
path: root/malloc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2005-10-03 20:44:20 +0000
committerJakub Jelinek <jakub@redhat.com>2005-10-03 20:44:20 +0000
commita5a11654ea5ea89bfffb295fbb2f17cbb45839b6 (patch)
tree2078fd7b828ae3b4c030e6722c53bdc81542a511 /malloc
parent6543cff055c298ea3ec718b356f6c2115e8797ae (diff)
downloadglibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.tar.gz
glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.tar.xz
glibc-a5a11654ea5ea89bfffb295fbb2f17cbb45839b6.zip
Updated to fedora-glibc-20051003T2040
Diffstat (limited to 'malloc')
-rw-r--r--malloc/Makefile2
-rw-r--r--malloc/arena.c21
-rw-r--r--malloc/malloc.c2
-rw-r--r--malloc/memusage.c60
-rw-r--r--malloc/obstack.h5
-rw-r--r--malloc/tst-mallocfork.c52
6 files changed, 116 insertions, 26 deletions
diff --git a/malloc/Makefile b/malloc/Makefile
index ca427077f3..c479da39b7 100644
--- a/malloc/Makefile
+++ b/malloc/Makefile
@@ -27,7 +27,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-mallocstate tst-mcheck tst-mallocfork
 test-srcs = tst-mtrace
 
 distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \
diff --git a/malloc/arena.c b/malloc/arena.c
index 8db255966d..a844392a6b 100644
--- a/malloc/arena.c
+++ b/malloc/arena.c
@@ -210,6 +210,10 @@ 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
@@ -223,7 +227,18 @@ ptmalloc_lock_all (void)
 
   if(__malloc_initialized < 1)
     return;
-  (void)mutex_lock(&list_lock);
+  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);
+    }
   for(ar_ptr = &main_arena;;) {
     (void)mutex_lock(&ar_ptr->mutex);
     ar_ptr = ar_ptr->next;
@@ -236,6 +251,8 @@ 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
@@ -245,6 +262,8 @@ 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;
diff --git a/malloc/malloc.c b/malloc/malloc.c
index 64050b4266..594d9c4d7a 100644
--- a/malloc/malloc.c
+++ b/malloc/malloc.c
@@ -4618,7 +4618,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 size";
+      errstr = "realloc(): invalid old size";
       goto errout;
     }
 
diff --git a/malloc/memusage.c b/malloc/memusage.c
index 49bcc6f289..f586ea61ba 100644
--- a/malloc/memusage.c
+++ b/malloc/memusage.c
@@ -793,14 +793,21 @@ dest (void)
 \e[00;34m   free|\e[0m %10lu   %12llu\n",
 	   (unsigned long long int) grand_total, (unsigned long int) peak_heap,
 	   (unsigned long int) peak_stack,
-	   calls[idx_malloc], (unsigned long long int) total[idx_malloc],
-	   failed[idx_malloc] ? "\e[01;41m" : "", failed[idx_malloc],
-	   calls[idx_realloc], (unsigned long long int) total[idx_realloc],
-	   failed[idx_realloc] ? "\e[01;41m" : "", failed[idx_realloc],
-	   inplace, decreasing,
-	   calls[idx_calloc], (unsigned long long int) total[idx_calloc],
-	   failed[idx_calloc] ? "\e[01;41m" : "", failed[idx_calloc],
-	   calls[idx_free], (unsigned long long int) total[idx_free]);
+	   (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) 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]);
 
   if (trace_mmap)
     fprintf (stderr, "\
@@ -809,17 +816,28 @@ dest (void)
 \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   (in place: %ld, dec: %ld)\n\
 \e[00;34m munmap|\e[0m %10lu   %12llu   %s%12lu\e[00;00m\n",
-	     calls[idx_mmap_r], (unsigned long long int) total[idx_mmap_r],
-	     failed[idx_mmap_r] ? "\e[01;41m" : "", failed[idx_mmap_r],
-	     calls[idx_mmap_w], (unsigned long long int) total[idx_mmap_w],
-	     failed[idx_mmap_w] ? "\e[01;41m" : "", failed[idx_mmap_w],
-	     calls[idx_mmap_a], (unsigned long long int) total[idx_mmap_a],
-	     failed[idx_mmap_a] ? "\e[01;41m" : "", failed[idx_mmap_a],
-	     calls[idx_mremap], (unsigned long long int) total[idx_mremap],
-	     failed[idx_mremap] ? "\e[01;41m" : "", failed[idx_mremap],
-	     inplace_mremap, decreasing_mremap,
-	     calls[idx_munmap], (unsigned long long int) total[idx_munmap],
-	     failed[idx_munmap] ? "\e[01;41m" : "", failed[idx_munmap]);
+	     (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]);
 
   /* Write out a histoogram of the sizes of the allocations.  */
   fprintf (stderr, "\e[01;32mHistogram for block sizes:\e[0;0m\n");
@@ -836,7 +854,7 @@ dest (void)
       {
 	percent = (histogram[cnt / 16] * 100) / calls_total;
 	fprintf (stderr, "%5d-%-5d%12lu ", cnt, cnt + 15,
-		 histogram[cnt / 16]);
+		 (unsigned long int) histogram[cnt / 16]);
 	if (percent == 0)
 	  fputs (" <1% \e[41;37m", stderr);
 	else
@@ -853,7 +871,7 @@ dest (void)
   if (large != 0)
     {
       percent = (large * 100) / calls_total;
-      fprintf (stderr, "   large   %12lu ", large);
+      fprintf (stderr, "   large   %12lu ", (unsigned long int) large);
       if (percent == 0)
 	fputs (" <1% \e[41;37m", stderr);
       else
diff --git a/malloc/obstack.h b/malloc/obstack.h
index d18ef40b6e..03f6ccb2ce 100644
--- a/malloc/obstack.h
+++ b/malloc/obstack.h
@@ -1,5 +1,6 @@
 /* obstack.h - object stack macros
-   Copyright (C) 1988-1994,1996-1999,2003,2004 Free Software Foundation, Inc.
+   Copyright (C) 1988-1994,1996-1999,2003,2004,2005
+	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.
 
@@ -446,7 +447,7 @@ __extension__								\
   (((const void **) ((h)->next_free += sizeof (void *)))[-1] = (aptr))
 
 # define obstack_int_grow_fast(h,aint)					\
-  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aptr))
+  (((int *) ((h)->next_free += sizeof (int)))[-1] = (aint))
 
 # define obstack_blank(h,length)					\
 ( (h)->temp = (length),							\
diff --git a/malloc/tst-mallocfork.c b/malloc/tst-mallocfork.c
new file mode 100644
index 0000000000..abbc9d83b6
--- /dev/null
+++ b/malloc/tst-mallocfork.c
@@ -0,0 +1,52 @@
+/* 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;
+  sigemptyset (&action.sa_mask);
+  action.sa_handler = sig_handler;
+
+  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"