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