Commit 89a69226 authored by Kirill Smelkov's avatar Kirill Smelkov

.

parent ea6a66e4
...@@ -40,6 +40,12 @@ cpdef enum: ...@@ -40,6 +40,12 @@ cpdef enum:
MADV_SEQUENTIAL = mman.MADV_SEQUENTIAL MADV_SEQUENTIAL = mman.MADV_SEQUENTIAL
MADV_WILLNEED = mman.MADV_WILLNEED MADV_WILLNEED = mman.MADV_WILLNEED
MADV_DONTNEED = mman.MADV_DONTNEED MADV_DONTNEED = mman.MADV_DONTNEED
MADV_FREE = mman.MADV_FREE
MADV_REMOVE = mman.MADV_REMOVE
MS_ASYNC = mman.MS_ASYNC
MS_SYNC = mman.MS_SYNC
MS_INVALIDATE = mman.MS_INVALIDATE
# incore returns bytearray vector indicating whether page of mem is in core or not. # incore returns bytearray vector indicating whether page of mem is in core or not.
# #
...@@ -78,7 +84,7 @@ def lock(const unsigned char[::1] mem not None, int flags): ...@@ -78,7 +84,7 @@ def lock(const unsigned char[::1] mem not None, int flags):
if err: if err:
PyErr_SetFromErrno(OSError) PyErr_SetFromErrno(OSError)
return # ok return
# unlock unlocks mem pages from being pinned in RAM. # unlock unlocks mem pages from being pinned in RAM.
...@@ -90,7 +96,7 @@ def unlock(const unsigned char[::1] mem not None): ...@@ -90,7 +96,7 @@ def unlock(const unsigned char[::1] mem not None):
if err: if err:
PyErr_SetFromErrno(OSError) PyErr_SetFromErrno(OSError)
return # ok return
from posix.types cimport off_t from posix.types cimport off_t
...@@ -114,7 +120,7 @@ def map_into_ro(unsigned char[::1] mem not None, int fd, off_t offset): ...@@ -114,7 +120,7 @@ def map_into_ro(unsigned char[::1] mem not None, int fd, off_t offset):
if addr == mman.MAP_FAILED: if addr == mman.MAP_FAILED:
PyErr_SetFromErrno(OSError) PyErr_SetFromErrno(OSError)
return # ok return
# unmap unmaps memory covered by mem. # unmap unmaps memory covered by mem.
def unmap(const unsigned char[::1] mem not None): def unmap(const unsigned char[::1] mem not None):
...@@ -125,7 +131,7 @@ def unmap(const unsigned char[::1] mem not None): ...@@ -125,7 +131,7 @@ def unmap(const unsigned char[::1] mem not None):
if err: if err:
PyErr_SetFromErrno(OSError) PyErr_SetFromErrno(OSError)
return # ok return
# advise advises kernel about use of mem's memory. # advise advises kernel about use of mem's memory.
...@@ -139,4 +145,18 @@ def advise(const unsigned char[::1] mem not None, int advice): ...@@ -139,4 +145,18 @@ def advise(const unsigned char[::1] mem not None, int advice):
if err: if err:
PyErr_SetFromErrno(OSError) PyErr_SetFromErrno(OSError)
return # ok return
# sync asks the kernel to synchronize the file with a memory map.
#
# see msync(2) for details.
def sync(const unsigned char[::1] mem not None, int flags):
cdef const void *addr = &mem[0]
cdef size_t size = mem.shape[0]
cdef err = mman.msync(<void *>addr, size, flags)
if err:
PyErr_SetFromErrno(OSError)
return
...@@ -26,6 +26,7 @@ from libc.signal cimport SIGBUS ...@@ -26,6 +26,7 @@ from libc.signal cimport SIGBUS
from libc.stdlib cimport abort from libc.stdlib cimport abort
from libc.string cimport strlen from libc.string cimport strlen
from posix.unistd cimport write, sleep from posix.unistd cimport write, sleep
from posix.types cimport off_t
from cpython.exc cimport PyErr_SetFromErrno from cpython.exc cimport PyErr_SetFromErrno
from cpython.pystate cimport PyGILState_Ensure, PyGILState_Release, PyGILState_STATE from cpython.pystate cimport PyGILState_Ensure, PyGILState_Release, PyGILState_STATE
...@@ -43,6 +44,18 @@ def read_nogil(const unsigned char[::1] mem not None) -> bytes: ...@@ -43,6 +44,18 @@ def read_nogil(const unsigned char[::1] mem not None) -> bytes:
return bytes(bytearray([b])) return bytes(bytearray([b]))
cdef extern from "<fcntl.h>" nogil:
int posix_fadvise(int fd, off_t offset, off_t len, int advice);
enum: POSIX_FADV_DONTNEED
# fadvise_dontneed teels the kernel that file<fd>[offset +len) is not needed.
#
# see fadvise(2) for details.
def fadvise_dontneed(int fd, off_t offset, off_t len):
cdef int err = posix_fadvise(fd, offset, len, POSIX_FADV_DONTNEED)
if err:
PyErr_SetFromErrno(OSError)
# ---- signal handling ---- # ---- signal handling ----
# XXX -> golang.signal ? # XXX -> golang.signal ?
......
...@@ -42,7 +42,7 @@ from zodbtools.util import ashex as h, fromhex ...@@ -42,7 +42,7 @@ from zodbtools.util import ashex as h, fromhex
from pytest import raises from pytest import raises
from six import reraise from six import reraise
from .internal import mm from .internal import mm
from .internal.wcfs_test import read_nogil, install_sigbus_trap from .internal.wcfs_test import read_nogil, install_sigbus_trap, fadvise_dontneed
# setup: # setup:
# - create test database, compute zurl and mountpoint for wcfs # - create test database, compute zurl and mountpoint for wcfs
...@@ -1553,11 +1553,17 @@ def test_wcfs_no_pin_twice(): ...@@ -1553,11 +1553,17 @@ def test_wcfs_no_pin_twice():
assert w.pinned == {2:at1} assert w.pinned == {2:at1}
# drop file[blk] from cache, access again -> no pin message sent the second time # drop file[blk] from cache, access again -> no pin message sent the second time
print('\n\n\n\n\nABCDEF\n\n\n') #
# ( we need both madvise(DONTNEED) and fadvise(DONTNEED) - given only one of
# those the kernel won't release the page from pagecache; madvise does
# not work without munlock. )
mm.unlock(f._blk(2))
mm.advise(f._blk(2), mm.MADV_DONTNEED) mm.advise(f._blk(2), mm.MADV_DONTNEED)
fadvise_dontneed(f.f.fileno(), 2*blksize, 1*blksize)
f.assertCache([0,0,0]) f.assertCache([0,0,0])
# XXX f.assertBlk(2, 'c2', {wl: {}})
f.assertCache([0,0,1])
# verify watching for 2 files over single watch link. # verify watching for 2 files over single watch link.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment