From owner-freebsd-bugs@FreeBSD.ORG Sun Mar 20 10:10:09 2005 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 9018916A4CE for ; Sun, 20 Mar 2005 10:10:09 +0000 (GMT) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5700B43D58 for ; Sun, 20 Mar 2005 10:10:09 +0000 (GMT) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) by freefall.freebsd.org (8.13.3/8.13.3) with ESMTP id j2KAA9BV095326 for ; Sun, 20 Mar 2005 10:10:09 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.13.3/8.13.1/Submit) id j2KAA9s9095325; Sun, 20 Mar 2005 10:10:09 GMT (envelope-from gnats) Resent-Date: Sun, 20 Mar 2005 10:10:09 GMT Resent-Message-Id: <200503201010.j2KAA9s9095325@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Dmitrij Tejblum Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AC95C16A4CE for ; Sun, 20 Mar 2005 10:06:54 +0000 (GMT) Received: from developer.yandex.ru (developer.yandex.ru [213.180.193.15]) by mx1.FreeBSD.org (Postfix) with ESMTP id E261143D49 for ; Sun, 20 Mar 2005 10:06:53 +0000 (GMT) (envelope-from tejblum@developer.yandex.ru) Received: from developer.yandex.ru (localhost [127.0.0.1]) by developer.yandex.ru (8.13.3/8.13.1) with ESMTP id j2KA6q9k047339 for ; Sun, 20 Mar 2005 13:06:52 +0300 (MSK) (envelope-from tejblum@developer.yandex.ru) Received: (from tejblum@localhost) by developer.yandex.ru (8.13.3/8.13.1/Submit) id j2KA6q4b047338; Sun, 20 Mar 2005 13:06:52 +0300 (MSK) (envelope-from tejblum) Message-Id: <200503201006.j2KA6q4b047338@developer.yandex.ru> Date: Sun, 20 Mar 2005 13:06:52 +0300 (MSK) From: Dmitrij Tejblum To: FreeBSD-gnats-submit@FreeBSD.org X-Send-Pr-Version: 3.113 Subject: bin/79048: realloc() copies data even when the size of allocated memory decrease X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list Reply-To: Dmitrij Tejblum List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 20 Mar 2005 10:10:09 -0000 >Number: 79048 >Category: bin >Synopsis: realloc() copies data even when the size of allocated memory decrease >Confidential: no >Severity: non-critical >Priority: low >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Mar 20 10:10:07 GMT 2005 >Closed-Date: >Last-Modified: >Originator: Dmitrij Tejblum >Release: FreeBSD 5.4-PRERELEASE i386 >Organization: >Environment: >Description: If a program malloc() a large piece of memory (e.g. p = malloc(1024000)) and then realloc() it to a smaller size (e.g. realloc(p, 512000)) realloc() allocate new piece of memory and copy the old piece to new one. The unnecessary reallocation also sometimes lead to allocation failures. But it is easy to mark the tail of old memory as free. >How-To-Repeat: >Fix: --- malloc.c Sun Mar 20 03:11:19 2005 +++ malloc.c Sun Mar 20 03:13:15 2005 @@ -286,6 +286,7 @@ static int extend_pgdir(u_long index); static void *imalloc(size_t size); static void ifree(void *ptr); static void *irealloc(void *ptr, size_t size); +static __inline void free_pages(void *ptr, u_long index, struct pginfo const *info); static void wrtmessage(const char *p1, const char *p2, const char *p3, const char *p4) @@ -787,10 +788,15 @@ irealloc(void *ptr, size_t size) if (!malloc_realloc && /* Unless we have to, */ size <= osize && /* .. or are too small, */ - size > (osize - malloc_pagesize)) { /* .. or can free a page, */ + size > malloc_maxsize) { /* .. or want to allocate a chunk */ if (malloc_junk) memset((u_char *)ptr + size, SOME_JUNK, osize-size); - return (ptr); /* ..don't do anything else. */ + if (size <= (osize - malloc_pagesize)) { /* have something to free */ + size_t nsize = pageround(size); + void *fptr = (u_char *)ptr + nsize; + free_pages(fptr, ptr2index(fptr), MALLOC_FIRST); + } + return (ptr); } } else if (*mp >= MALLOC_MAGIC) { /* Chunk allocation */ >Release-Note: >Audit-Trail: >Unformatted: