apr-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From s.@apache.org
Subject svn commit: r1072165 - in /apr/apr/trunk: CHANGES configure.in memory/unix/apr_pools.c
Date Fri, 18 Feb 2011 21:51:56 GMT
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 <sr myarm.com>]
 

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 <unistd.h>     /* for getpid */
+#include <unistd.h>     /* for getpid and sysconf */
 #endif
 
+#if APR_ALLOCATOR_USES_MMAP
+#include <sys/mman.h>
+#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



Mime
View raw message