This is the mail archive of the libc-alpha@sources.redhat.com mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: malloc using mprotect


On Fri, Aug 10, 2001 at 02:31:47PM +0200, Wolfram Gloger wrote:
> Hello,
> 
> > No, that will actually take one VMA too, provided it is anonymous private
> > mapping. mmap does some minimal merging
> >         /* Can we just expand an old anonymous mapping? */
> 
> Ok, how about the appended simple patch then?  Behaviour should then
> be the same as with sbrk().
> 
> Regards,
> Wolfram.
> 
> 2001-08-10  Wolfram Gloger  <wg@malloc.de>
> 
> 	* malloc/malloc.c (grow_heap): Use mmap() rather than mprotect()
> 	to allocate new memory, for better performance with Linux-2.4.x.
> 

I think you want to use it instead of the first mprotect too, since
otherwise consecutive new arenas will not be merged into one huge vma.
Tested on 2.4.7 kernel where it creates just one vma for all new arenas,
2.4.2 kernel apparently does not merge anything but that's history.
Testing program for IA-32 was:
#include <sys/mman.h>
#include <malloc.h>

int main(void)
{
  mmap(0x08100000, 0x40000000 - 0x08100000, PROT_NONE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0);
  while (1) malloc(1024);
}
where the first call almost disabled sbrk heap.
>From looking at mm/mmap.c and mm/mprotect.c, mmap shouldn't be much slower
than mprotect if the old mapping is PROT_NONE, am I right, David/Alan?
It can do some vma searches which mprotect would not do, but those will be
certainly faster with just a few vmas than with thousands of vmas for
mprotect. As there cannot be any pages mapped, zap_page_range in do_munmap
should be as fast as change_page_range in mprotect.
So this looks like a good solution.

--- malloc/malloc.c.jj	Fri Jul 20 06:44:54 2001
+++ malloc/malloc.c	Fri Aug 10 08:48:25 2001
@@ -2050,7 +2050,8 @@ new_heap(size) size_t size;
       return 0;
     }
   }
-  if(mprotect(p2, size, PROT_READ|PROT_WRITE) != 0) {
+  if(MMAP(p2, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED)
+     == (char *) MAP_FAILED) {
     munmap(p2, HEAP_MAX_SIZE);
     return 0;
   }
@@ -2078,7 +2079,8 @@ grow_heap(h, diff) heap_info *h; long di
     new_size = (long)h->size + diff;
     if(new_size > HEAP_MAX_SIZE)
       return -1;
-    if(mprotect((char *)h + h->size, diff, PROT_READ|PROT_WRITE) != 0)
+    if(MMAP((char *)h + h->size, diff, PROT_READ|PROT_WRITE,
+	    MAP_PRIVATE|MAP_FIXED) == (char *) MAP_FAILED)
       return -2;
   } else {
     new_size = (long)h->size + diff;


	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]