diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | malloc/arena.c | 80 |
2 files changed, 51 insertions, 33 deletions
diff --git a/ChangeLog b/ChangeLog index 531d6b9a5c..c575591e75 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2007-12-11 Ulrich Drepper <drepper@redhat.com> + * malloc/arena.c (grow_heap): Split out code to shrink heap into... + (shrink_heap): ... this new function. + (heap_trim): Call shrink_heap instead of grow_heap. + * malloc/malloc.c (_int_malloc): sYSMALLOc might fail, in this case don't call alloc_perturb. diff --git a/malloc/arena.c b/malloc/arena.c index 4cbb4dc307..9932ee049b 100644 --- a/malloc/arena.c +++ b/malloc/arena.c @@ -704,8 +704,8 @@ new_heap(size, top_pad) size_t size, top_pad; return h; } -/* Grow or shrink a heap. size is automatically rounded up to a - multiple of the page size if it is positive. */ +/* Grow a heap. size is automatically rounded up to a + multiple of the page size. */ static int #if __STD_C @@ -717,41 +717,55 @@ grow_heap(h, diff) heap_info *h; long diff; size_t page_mask = malloc_getpagesize - 1; long new_size; - 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) - 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; - } - } 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. */ + diff = (diff + page_mask) & ~page_mask; + new_size = (long)h->size + diff; + if((unsigned long) new_size > (unsigned long) 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; + } + + h->size = new_size; + return 0; +} + +/* Shrink a heap. */ + +static int +#if __STD_C +shrink_heap(heap_info *h, long diff) +#else +shrink_heap(h, diff) heap_info *h; long diff; +#endif +{ + long new_size; + + 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)) + if (__builtin_expect (__libc_enable_secure, 0)) #else - if (1) + 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; - } + { + 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); + else + madvise ((char *)h + new_size, diff, MADV_DONTNEED); #endif - /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ - } + /*fprintf(stderr, "shrink %p %08lx\n", h, new_size);*/ + h->size = new_size; return 0; } @@ -811,7 +825,7 @@ heap_trim(heap, pad) heap_info *heap; size_t pad; if(extra < (long)pagesz) return 0; /* Try to shrink. */ - if(grow_heap(heap, -extra) != 0) + if(shrink_heap(heap, extra) != 0) return 0; ar_ptr->system_mem -= extra; arena_mem -= extra; |