Return-Path: Delivered-To: apmail-apr-commits-archive@www.apache.org Received: (qmail 22447 invoked from network); 18 Feb 2011 21:52:21 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.3) by minotaur.apache.org with SMTP; 18 Feb 2011 21:52:21 -0000 Received: (qmail 88009 invoked by uid 500); 18 Feb 2011 21:52:21 -0000 Delivered-To: apmail-apr-commits-archive@apr.apache.org Received: (qmail 87964 invoked by uid 500); 18 Feb 2011 21:52:21 -0000 Mailing-List: contact commits-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: Reply-To: dev@apr.apache.org List-Id: Delivered-To: mailing list commits@apr.apache.org Received: (qmail 87957 invoked by uid 99); 18 Feb 2011 21:52:21 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Feb 2011 21:52:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 18 Feb 2011 21:52:17 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 86183238896F; Fri, 18 Feb 2011 21:51:56 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1072165 - in /apr/apr/trunk: CHANGES configure.in memory/unix/apr_pools.c Date: Fri, 18 Feb 2011 21:51:56 -0000 To: commits@apr.apache.org From: sf@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20110218215156.86183238896F@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: sf Date: Fri Feb 18 21:51:56 2011 New Revision: 1072165 URL: http://svn.apache.org/viewvc?rev=1072165&view=rev Log: Add new configure option --enable-allocator-uses-mmap to use mmap instead of malloc in apr_allocator_alloc(). This greatly reduces memory fragmentation with malloc implementations (e.g. glibc) that don't handle allocationss of a page-size-multiples in an efficient way. It also makes apr_allocator_max_free_set() actually have some effect on such platforms. The handling of page sizes other than 4k seems like a lot of trouble for a very small number of platforms, but there does not seem to be a reasonable way to check this at compile time. Modified: apr/apr/trunk/CHANGES apr/apr/trunk/configure.in apr/apr/trunk/memory/unix/apr_pools.c Modified: apr/apr/trunk/CHANGES URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=1072165&r1=1072164&r2=1072165&view=diff ============================================================================== --- apr/apr/trunk/CHANGES [utf-8] (original) +++ apr/apr/trunk/CHANGES [utf-8] Fri Feb 18 21:51:56 2011 @@ -1,6 +1,13 @@ -*- coding: utf-8 -*- Changes for APR 2.0.0 + *) Add new configure option --enable-allocator-uses-mmap to use mmap + instead of malloc in apr_allocator_alloc(). This greatly reduces + memory fragmentation with malloc implementations (e.g. glibc) that + don't handle allocationss of a page-size-multiples in an efficient way. + It also makes apr_allocator_max_free_set() actually have some effect + on such platforms. [Stefan Fritsch] + *) apr_dbd_oracle: fix endianness issue in prepared statements PR 50690 [Stefan Ruppert ] Modified: apr/apr/trunk/configure.in URL: http://svn.apache.org/viewvc/apr/apr/trunk/configure.in?rev=1072165&r1=1072164&r2=1072165&view=diff ============================================================================== --- apr/apr/trunk/configure.in (original) +++ apr/apr/trunk/configure.in Fri Feb 18 21:51:56 2011 @@ -1404,6 +1404,18 @@ if test "$netdbh" = "1"; then fi fi +AC_ARG_ENABLE(allocator-uses-mmap, + [ --enable-allocator-uses-mmap Use mmap in apr_allocator instead of malloc ], + [ if test "$enableval" = "yes"; then + APR_IFALLYES(header:sys/mman.h func:mmap func:munmap define:MAP_ANON, + [AC_DEFINE(APR_ALLOCATOR_USES_MMAP, 1, + [Define if apr_allocator should use mmap]) ], + [AC_MSG_ERROR([mmap()/MAP_ANON not supported]) ] + ) + fi ], + [ ] +) + dnl ----------------------------- Checks for standard typedefs AC_TYPE_OFF_T AC_TYPE_PID_T Modified: apr/apr/trunk/memory/unix/apr_pools.c URL: http://svn.apache.org/viewvc/apr/apr/trunk/memory/unix/apr_pools.c?rev=1072165&r1=1072164&r2=1072165&view=diff ============================================================================== --- apr/apr/trunk/memory/unix/apr_pools.c (original) +++ apr/apr/trunk/memory/unix/apr_pools.c Fri Feb 18 21:51:56 2011 @@ -36,9 +36,12 @@ #endif #if APR_HAVE_UNISTD_H -#include /* for getpid */ +#include /* for getpid and sysconf */ #endif +#if APR_ALLOCATOR_USES_MMAP +#include +#endif /* * Magic numbers @@ -47,8 +50,15 @@ #define MIN_ALLOC 8192 #define MAX_INDEX 20 +#if APR_ALLOCATOR_USES_MMAP && defined(_SC_PAGESIZE) +static unsigned int boundary_index; +static unsigned int boundary_size; +#define BOUNDARY_INDEX boundary_index +#define BOUNDARY_SIZE boundary_size +#else #define BOUNDARY_INDEX 12 #define BOUNDARY_SIZE (1 << BOUNDARY_INDEX) +#endif /* * Timing constants for killing subprocesses @@ -131,7 +141,11 @@ APR_DECLARE(void) apr_allocator_destroy( ref = &allocator->free[index]; while ((node = *ref) != NULL) { *ref = node->next; +#if APR_ALLOCATOR_USES_MMAP + munmap(node, (node->index+1) << BOUNDARY_INDEX); +#else free(node); +#endif } } @@ -323,7 +337,12 @@ apr_memnode_t *allocator_alloc(apr_alloc /* If we haven't got a suitable node, malloc a new one * and initialize it. */ +#if APR_ALLOCATOR_USES_MMAP + if ((node = mmap(NULL, size, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANON, -1, 0)) == MAP_FAILED) +#else if ((node = malloc(size)) == NULL) +#endif return NULL; node->next = NULL; @@ -400,7 +419,11 @@ void allocator_free(apr_allocator_t *all while (freelist != NULL) { node = freelist; freelist = node->next; +#if APR_ALLOCATOR_USES_MMAP + munmap(node, (node->index+1) << BOUNDARY_INDEX); +#else free(node); +#endif } } @@ -548,6 +571,14 @@ APR_DECLARE(apr_status_t) apr_pool_initi if (apr_pools_initialized++) return APR_SUCCESS; +#if APR_ALLOCATOR_USES_MMAP && defined(_SC_PAGESIZE) + boundary_size = sysconf(_SC_PAGESIZE); + boundary_index = 12; + while ( (1 << boundary_index) < boundary_size) + boundary_index++; + boundary_size = (1 << boundary_index); +#endif + if ((rv = apr_allocator_create(&global_allocator)) != APR_SUCCESS) { apr_pools_initialized = 0; return rv; @@ -923,6 +954,7 @@ APR_DECLARE(apr_status_t) apr_pool_creat if (!apr_pools_initialized) return APR_ENOPOOL; if ((pool_allocator = allocator) == NULL) { +#if !APR_ALLOCATOR_USES_MMAP if ((pool_allocator = malloc(MIN_ALLOC)) == NULL) { if (abort_fn) abort_fn(APR_ENOMEM); @@ -936,6 +968,21 @@ APR_DECLARE(apr_status_t) apr_pool_creat node->index = 1; node->first_avail = (char *)node + APR_MEMNODE_T_SIZE; node->endp = (char *)pool_allocator + MIN_ALLOC; +#else + if (apr_allocator_create(&pool_allocator) != APR_SUCCESS) { + if (abort_fn) + abort_fn(APR_ENOMEM); + + return APR_ENOMEM; + } + if ((node = allocator_alloc(pool_allocator, + MIN_ALLOC - APR_MEMNODE_T_SIZE)) == NULL) { + if (abort_fn) + abort_fn(APR_ENOMEM); + + return APR_ENOMEM; + } +#endif } else if ((node = allocator_alloc(pool_allocator, MIN_ALLOC - APR_MEMNODE_T_SIZE)) == NULL) { @@ -1331,6 +1378,14 @@ APR_DECLARE(apr_status_t) apr_pool_initi if (apr_pools_initialized++) return APR_SUCCESS; +#if APR_ALLOCATOR_USES_MMAP && defined(_SC_PAGESIZE) + boundary_size = sysconf(_SC_PAGESIZE); + boundary_index = 12; + while ( (1 << boundary_index) < boundary_size) + boundary_index++; + boundary_size = (1 << boundary_index); +#endif + /* Since the debug code works a bit differently then the * regular pools code, we ask for a lock here. The regular * pools code has got this lock embedded in the global