Author: Greg Price <[email protected]>
Branch: 
Changeset: r62539:5adf8d0c5c56
Date: 2013-03-19 19:38 -0700
http://bitbucket.org/pypy/pypy/changeset/5adf8d0c5c56/

Log:    rmmap: Add partial unmap

diff --git a/rpython/rlib/rmmap.py b/rpython/rlib/rmmap.py
--- a/rpython/rlib/rmmap.py
+++ b/rpython/rlib/rmmap.py
@@ -287,6 +287,15 @@
         self.data = data
         self.size = size
 
+    def unmap_range(self, offset, size):
+        """Unmap (a portion of) the mapped range.  POSIX only.
+
+        Per munmap(1), the offset must be a multiple of the page size,
+        and the size will be rounded up to a multiple of the page size.
+        """
+        assert _POSIX
+        return c_munmap_safe(self.getptr(offset), size)
+
     def close(self):
         if _MS_WINDOWS:
             if self.size > 0:
@@ -307,7 +316,7 @@
                 os.close(self.fd)
                 self.fd = -1
             if self.size > 0:
-                c_munmap_safe(self.getptr(0), self.size)
+                self.unmap_range(0, self.size)
                 self.setdata(NODATA, 0)
 
     def __del__(self):
@@ -677,6 +686,11 @@
         m.setdata(res, map_size)
         return m
 
+    def alloc_hinted(hintp, map_size):
+        flags = MAP_PRIVATE | MAP_ANONYMOUS
+        prot = PROT_EXEC | PROT_READ | PROT_WRITE
+        return c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
+
     # XXX is this really necessary?
     class Hint:
         pos = -0x4fff0000   # for reproducible results
@@ -695,15 +709,11 @@
             if res == rffi.cast(PTR, 0):
                 raise MemoryError
             return res
-        flags = MAP_PRIVATE | MAP_ANONYMOUS
-        prot = PROT_EXEC | PROT_READ | PROT_WRITE
-        hintp = rffi.cast(PTR, hint.pos)
-        res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
+        res = alloc_hinted(rffi.cast(PTR, hint.pos), map_size)
         if res == rffi.cast(PTR, -1):
             # some systems (some versions of OS/X?) complain if they
             # are passed a non-zero address.  Try again.
-            hintp = rffi.cast(PTR, 0)
-            res = c_mmap_safe(hintp, map_size, prot, flags, -1, 0)
+            res = alloc_hinted(rffi.cast(PTR, 0), map_size)
             if res == rffi.cast(PTR, -1):
                 raise MemoryError
         else:
diff --git a/rpython/rlib/test/test_rmmap.py b/rpython/rlib/test/test_rmmap.py
--- a/rpython/rlib/test/test_rmmap.py
+++ b/rpython/rlib/test/test_rmmap.py
@@ -1,6 +1,7 @@
 from rpython.tool.udir import udir
 import os, sys, py
 from rpython.rtyper.test.test_llinterp import interpret
+from rpython.rtyper.lltypesystem import rffi, lltype
 from rpython.rlib.rarithmetic import intmask
 from rpython.rlib import rmmap as mmap
 from rpython.rlib.rmmap import RTypeError, RValueError, alloc, free
@@ -64,6 +65,29 @@
         
         f.close()
 
+    def test_unmap(self):
+        f = open(self.tmpname + "-unmap", "w+")
+        left, right, size = 100, 200, 500  # in pages
+
+        f.write(size*4096*"c")
+        f.flush()
+
+        def func(no):
+            m = mmap.mmap(no, size*4096)
+            m.unmap_range(left*4096, (right-left)*4096)
+            m.read(1)
+            m.seek(right*4096)
+            m.read(1)
+
+            def in_map(m, offset):
+                return rffi.ptradd(m.data, offset)
+            def as_num(ptr):
+                return rffi.cast(lltype.Unsigned, ptr)
+            res = mmap.alloc_hinted(in_map(m, (left+right)/2 * 4096), 4096)
+            assert as_num(in_map(m, left*4096)) <= as_num(res) < 
as_num(in_map(m, right*4096))
+        interpret(func, [f.fileno()])
+        f.close()
+
     def test_close(self):
         f = open(self.tmpname + "c", "w+")
         
@@ -80,6 +104,7 @@
             else:
                 raise Exception("Did not raise")
         interpret(func, [f.fileno()])
+        f.close()
 
     def test_read_byte(self):
         f = open(self.tmpname + "d", "w+")
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to