summaryrefslogtreecommitdiff
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)
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"