diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | sysdeps/mach/hurd/mmap.c | 46 |
2 files changed, 37 insertions, 15 deletions
@@ -3,6 +3,12 @@ * sysdeps/mach/hurd/socket.c (__socket): Return EAFNOSUPPORT instead of the non-standard EPFNOSUPPORT. +2011-12-26 Samuel Thibault <samuel.thibault@ens-lyon.org> + + * sysdeps/mach/hurd/mmap.c (__mmap): When MAPADDR is nonzero, 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. + 2012-01-21 Ulrich Drepper <drepper@gmail.com> * wcsmbs/uchar.h: Test __STDC_VERSION__. diff --git a/sysdeps/mach/hurd/mmap.c b/sysdeps/mach/hurd/mmap.c index 1d1460c..e08e999 100644 --- a/sysdeps/mach/hurd/mmap.c +++ b/sysdeps/mach/hurd/mmap.c @@ -1,4 +1,4 @@ -/* Copyright (C) 1994,1995,1996,1997,1999,2002,2003,2004 +/* Copyright (C) 1994,1995,1996,1997,1999,2002,2003,2004,2012 Free Software Foundation, Inc. This file is part of the GNU C Library. @@ -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 == NULL); - 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 != NULL) + 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 == NULL, 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 != NULL) 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 |