bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH,HURD] mmap: Use addr parameter even without MAP_FIXED


From: Samuel Thibault
Subject: [PATCH,HURD] mmap: Use addr parameter even without MAP_FIXED
Date: Tue, 27 Dec 2011 16:13:18 +0100
User-agent: Mutt/1.5.21+34 (58baf7c9f32f) (2010-12-30)

Hello,

POSIX says that mmap should take the addr parameter as a suggestion in
an implementation-defined manner.  On GNU/Hurd it's atm not used at all.
Some applications (such as firefox) frown on this and just busy-loop.

This makes mmap try with anywhere = 0 when addr is non-zero, before
trying with anywhere = 1 if it failed.

Samuel

2011-12-26  Samuel Thibault  <samuel.thibault@ens-lyon.org>

        * sysdeps/mach/hurd/mmap.c (__mmap): When `mapaddr' is non zero, try
        __vm_allocate and __vm_map with `anywhere' set to 0 first, and try with
        `anywhere' set to 1 only on KERN_NO_SPACE error.

---
 mmap.c |   44 ++++++++++++++++++++++++++++++--------------
 1 file changed, 30 insertions(+), 14 deletions(-)
diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c
index 1d1460c..96d7661 100644
--- a/sysdeps/mach/hurd/mmap.c
+++ b/sysdeps/mach/hurd/mmap.c
@@ -51,15 +51,20 @@ __mmap (__ptr_t addr, size_t len, int prot, int flags, int 
fd, off_t offset)
     {
       /* vm_allocate has (a little) less overhead in the kernel too.  */
       err = __vm_allocate (__mach_task_self (), &mapaddr, len,
-                          !(flags & MAP_FIXED));
+                          !mapaddr);
 
-      if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+      if (err == KERN_NO_SPACE)
        {
-         /* XXX this is not atomic as it is in unix! */
-         /* The region is already allocated; deallocate it first.  */
-         err = __vm_deallocate (__mach_task_self (), mapaddr, len);
-         if (!err)
-           err = __vm_allocate (__mach_task_self (), &mapaddr, len, 0);
+         if (flags & MAP_FIXED)
+           {
+             /* XXX this is not atomic as it is in unix! */
+             /* The region is already allocated; deallocate it first.  */
+             err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+             if (!err)
+               err = __vm_allocate (__mach_task_self (), &mapaddr, len, 0);
+           }
+         else if (mapaddr)
+           err = __vm_allocate (__mach_task_self (), &mapaddr, len, 1);
        }
 
       return err ? (__ptr_t) (long int) __hurd_fail (err) : (__ptr_t) mapaddr;
@@ -135,21 +140,32 @@ __mmap (__ptr_t addr, size_t len, int prot, int flags, 
int fd, off_t offset)
 
   err = __vm_map (__mach_task_self (),
                  &mapaddr, (vm_size_t) len, (vm_address_t) 0,
-                 ! (flags & MAP_FIXED),
+                 !mapaddr,
                  memobj, (vm_offset_t) offset,
                  ! (flags & MAP_SHARED),
                  vmprot, VM_PROT_ALL,
                  (flags & MAP_SHARED) ? VM_INHERIT_SHARE : VM_INHERIT_COPY);
 
-  if (err == KERN_NO_SPACE && (flags & MAP_FIXED))
+  if (err == KERN_NO_SPACE)
     {
-      /* XXX this is not atomic as it is in unix! */
-      /* The region is already allocated; deallocate it first.  */
-      err = __vm_deallocate (__mach_task_self (), mapaddr, len);
-      if (! err)
+      if (flags & MAP_FIXED)
+       {
+         /* XXX this is not atomic as it is in unix! */
+         /* The region is already allocated; deallocate it first.  */
+         err = __vm_deallocate (__mach_task_self (), mapaddr, len);
+         if (! err)
+           err = __vm_map (__mach_task_self (),
+                           &mapaddr, (vm_size_t) len, (vm_address_t) 0,
+                           0, memobj, (vm_offset_t) offset,
+                           ! (flags & MAP_SHARED),
+                           vmprot, VM_PROT_ALL,
+                           (flags & MAP_SHARED) ? VM_INHERIT_SHARE
+                           : VM_INHERIT_COPY);
+       }
+      else if (mapaddr)
        err = __vm_map (__mach_task_self (),
                        &mapaddr, (vm_size_t) len, (vm_address_t) 0,
-                       0, memobj, (vm_offset_t) offset,
+                       1, memobj, (vm_offset_t) offset,
                        ! (flags & MAP_SHARED),
                        vmprot, VM_PROT_ALL,
                        (flags & MAP_SHARED) ? VM_INHERIT_SHARE



reply via email to

[Prev in Thread] Current Thread [Next in Thread]