From f163450fc0969ebd6f63c5d9bd059f6f0d107d75 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 27 Dec 2007 09:14:45 +0000 Subject: Updated to fedora-glibc-20071227T0908 --- malloc/Makefile | 4 +-- malloc/malloc.c | 85 ++++++++++++++++++++++++++++++++++++++++++++---------- malloc/tst-trim1.c | 56 +++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 18 deletions(-) create mode 100644 malloc/tst-trim1.c (limited to 'malloc') diff --git a/malloc/Makefile b/malloc/Makefile index c39eae5474..22b14eac77 100644 --- a/malloc/Makefile +++ b/malloc/Makefile @@ -1,4 +1,4 @@ -# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006 +# Copyright (C) 1991-1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 # Free Software Foundation, Inc. # This file is part of the GNU C Library. @@ -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-mallocfork + tst-mallocstate tst-mcheck tst-mallocfork tst-trim1 test-srcs = tst-mtrace distribute = thread-m.h mtrace.pl mcheck-init.c stackinfo.h memusage.h \ diff --git a/malloc/malloc.c b/malloc/malloc.c index 1e716089a2..fc8a83c328 100644 --- a/malloc/malloc.c +++ b/malloc/malloc.c @@ -1592,7 +1592,7 @@ static Void_t* _int_pvalloc(mstate, size_t); 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 int mTRIm(mstate, size_t); static size_t mUSABLe(Void_t*); static void mSTATs(void); static int mALLOPt(int, int); @@ -2739,8 +2739,6 @@ static void do_check_malloc_state(mstate av) mchunkptr p; mchunkptr q; mbinptr b; - unsigned int binbit; - int empty; unsigned int idx; INTERNAL_SIZE_T size; unsigned long total = 0; @@ -2810,8 +2808,8 @@ static void do_check_malloc_state(mstate av) /* binmap is accurate (except for bin 1 == unsorted_chunks) */ if (i >= 2) { - binbit = get_binmap(av,i); - empty = last(b) == b; + unsigned int binbit = get_binmap(av,i); + int empty = last(b) == b; if (!binbit) assert(empty); else if (!empty) @@ -3888,6 +3886,12 @@ public_cALLOc(size_t n, size_t elem_size) oldtopsize < mp_.sbrk_base + av->max_system_mem - (char *)oldtop) oldtopsize = (mp_.sbrk_base + av->max_system_mem - (char *)oldtop); #endif + if (av != &main_arena) + { + heap_info *heap = heap_for_ptr (oldtop); + if (oldtopsize < (char *) heap + heap->mprotect_size - (char *) oldtop) + oldtopsize = (char *) heap + heap->mprotect_size - (char *) oldtop; + } #endif mem = _int_malloc(av, sz); @@ -4013,13 +4017,22 @@ public_cFREe(Void_t* m) int public_mTRIm(size_t s) { - int result; + int result = 0; if(__malloc_initialized < 0) ptmalloc_init (); - (void)mutex_lock(&main_arena.mutex); - result = mTRIm(s); - (void)mutex_unlock(&main_arena.mutex); + + mstate ar_ptr = &main_arena; + do + { + (void) mutex_lock (&ar_ptr->mutex); + result |= mTRIm (ar_ptr, s); + (void) mutex_unlock (&ar_ptr->mutex); + + ar_ptr = ar_ptr->next; + } + while (ar_ptr != &main_arena); + return result; } @@ -5489,20 +5502,60 @@ _int_pvalloc(av, bytes) mstate av, size_t bytes; */ #if __STD_C -int mTRIm(size_t pad) +static int mTRIm(mstate av, size_t pad) #else -int mTRIm(pad) size_t pad; +static int mTRIm(av, pad) mstate av; size_t pad; #endif { - mstate av = &main_arena; /* already locked */ - /* Ensure initialization/consolidation */ - malloc_consolidate(av); + malloc_consolidate (av); + + const size_t ps = mp_.pagesize; + int psindex = bin_index (ps); + const size_t psm1 = ps - 1; + + int result = 0; + for (int i = 1; i < NBINS; ++i) + if (i == 1 || i >= psindex) + { + mbinptr bin = bin_at (av, i); + + for (mchunkptr p = last (bin); p != bin; p = p->bk) + { + INTERNAL_SIZE_T size = chunksize (p); + + if (size > psm1 + sizeof (struct malloc_chunk)) + { + /* See whether the chunk contains at least one unused page. */ + char *paligned_mem = (char *) (((uintptr_t) p + + sizeof (struct malloc_chunk) + + psm1) & ~psm1); + + assert ((char *) chunk2mem (p) + 4 * SIZE_SZ <= paligned_mem); + assert ((char *) p + size > paligned_mem); + + /* This is the size we could potentially free. */ + size -= paligned_mem - (char *) p; + + if (size > psm1) + { +#ifdef MALLOC_DEBUG + /* When debugging we simulate destroying the memory + content. */ + memset (paligned_mem, 0x89, size & ~psm1); +#endif + madvise (paligned_mem, size & ~psm1, MADV_DONTNEED); + + result = 1; + } + } + } + } #ifndef MORECORE_CANNOT_TRIM - return sYSTRIm(pad, av); + return result | (av == &main_arena ? sYSTRIm (pad, av) : 0); #else - return 0; + return result; #endif } diff --git a/malloc/tst-trim1.c b/malloc/tst-trim1.c new file mode 100644 index 0000000000..310707e0e1 --- /dev/null +++ b/malloc/tst-trim1.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +#define N 10000 + +static void *arr[N]; + +static int +do_test (void) +{ + for (int i = 0; i < N; ++i) + { + size_t size = random () % 16384; + + if ((arr[i] = malloc (size)) == NULL) + { + nomem: + puts ("not enough memory"); + return 0; + } + + memset (arr[i], size, size); + } + + void *p = malloc (256); + if (p == NULL) + goto nomem; + memset (p, 1, 256); + + puts ("=================================================================="); + + for (int i = 0; i < N; ++i) + if (i % 13 != 0) + free (arr[i]); + + puts ("=================================================================="); + + malloc_trim (0); + + puts ("=================================================================="); + + p = malloc (30000); + if (p == NULL) + goto nomem; + + memset (p, 2, 30000); + + malloc_trim (0); + + return 0; +} + +#define TEST_FUNCTION do_test () +#include "../test-skeleton.c" -- cgit v1.2.3