Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 113 lines (106 sloc) 3.854 kb
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
1 # Low-level routines
2 # These are needed for things like MAP_ANONYMOUS
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
3 function mmap(len::Integer, prot::Integer, flags::Integer, fd::Integer, offset::FileOffset)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
4 const pagesize::Int = 4096
5 # Check that none of the computations will overflow
6 if len > typemax(Int)-pagesize
7 error("Cannot map such a large buffer")
8 end
9 # Set the offset to a page boundary
10 offset_page::FileOffset = ifloor(offset/pagesize)*pagesize
11 len_page::Int = (offset-offset_page) + len
12 # Mmap the file
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
13 p = ccall(:mmap, Ptr{Void}, (Ptr{Void}, Int, Int32, Int32, Int32, FileOffset), C_NULL, len_page, prot, flags, fd, offset_page)
81dc5fc @iLeopard66 Fix #1138
iLeopard66 authored
14 if convert(Int,p) == -1
366560e @StefanKarpinski Massive super-commit removing current_output_stream [closes #754]
StefanKarpinski authored
15 error("Memory mapping failed", strerror())
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
16 end
17 # Also return a pointer that compensates for any adjustment in the offset
18 return p, int(offset-offset_page)
19 end
20
21 # Before mapping, grow the file to sufficient size
22 # (Required if you're going to write to a new memory-mapped file)
23 #
24 # Note: a few mappable streams do not support lseek. When Julia
25 # supports structures in ccall, switch to fstat.
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
26 function mmap_grow(len::Integer, prot::Integer, flags::Integer, fd::Integer, offset::FileOffset)
27 const SEEK_SET::Int32 = 0
28 const SEEK_CUR::Int32 = 1
29 const SEEK_END::Int32 = 2
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
30 # Save current file position so we can restore it later
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
31 cpos = ccall(:lseek, FileOffset, (Int32, FileOffset, Int32), fd, 0, SEEK_CUR)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
32 if cpos < 0
33 error(strerror())
34 end
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
35 filelen = ccall(:lseek, FileOffset, (Int32, FileOffset, Int32), fd, 0, SEEK_END)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
36 if filelen < 0
37 error(strerror())
38 end
39 if (filelen < offset + len)
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
40 n = ccall(:pwrite, Int, (Int32, Ptr{Void}, Int, FileOffset), fd, int8([0]), 1, offset + len - 1)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
41 if (n < 1)
42 error(strerror())
43 end
44 end
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
45 cpos = ccall(:lseek, FileOffset, (Int32, FileOffset, Int32), fd, cpos, SEEK_SET)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
46 return mmap(len, prot, flags, fd, offset)
47 end
48
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
49 function munmap(p::Ptr,len::Integer)
50 ret = ccall(:munmap,Int32,(Ptr{Void},Int),p,len)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
51 if ret != 0
52 error(strerror())
53 end
54 end
55
45aa368 @timholy Add support for syncing mmap.
timholy authored
56 const MS_ASYNC = 1
57 const MS_INVALIDATE = 2
58 const MS_SYNC = 4
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
59 function msync(p::Ptr, len::Integer, flags::Integer)
60 ret = ccall(:msync, Int32, (Ptr{Void}, Int, Int32), p, len, flags)
45aa368 @timholy Add support for syncing mmap.
timholy authored
61 if ret != 0
62 error(strerror())
63 end
64 end
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
65
66 # Higher-level functions
67 # Determine a stream's read/write mode, and return prot & flags
68 # appropriate for mmap
69 function mmap_stream_settings(s::IOStream)
9a95792 @carlobaldassi mmap: fixed types
carlobaldassi authored
70 const PROT_READ::Int32 = 1
71 const PROT_WRITE::Int32 = 2
72 const MAP_SHARED::Int32 = 1
73 const F_GETFL::Int32 = 3
74 mode = ccall(:fcntl,Int32,(Int32,Int32),fd(s),F_GETFL)
00118c2 @timholy Allow mmap constructor to grow file to the needed length.
timholy authored
75 mode = mode & 3
76 if mode == 0
77 prot = PROT_READ
78 elseif mode == 1
79 prot = PROT_WRITE
80 else
81 prot = PROT_READ | PROT_WRITE
82 end
83 if prot & PROT_READ == 0
84 error("For mmap, you need read permissions on the file (choose r+)")
85 end
86 flags = MAP_SHARED
87 return prot, flags, (prot & PROT_WRITE) > 0
88 end
89
90 # Mmapped-array constructor
91 function mmap_array{T,N}(::Type{T}, dims::NTuple{N,Int}, s::IOStream, offset::FileOffset)
92 prot, flags, iswrite = mmap_stream_settings(s)
93 len = prod(dims)*sizeof(T)
94 if iswrite
95 pmap, delta = mmap_grow(len, prot, flags, fd(s), offset)
96 else
97 pmap, delta = mmap(len, prot, flags, fd(s), offset)
98 end
99 A = pointer_to_array(pointer(T, uint(pmap)+delta), dims)
100 finalizer(A,x->munmap(pmap,len+delta))
101 return A
102 end
103 mmap_array{T,N}(::Type{T}, dims::NTuple{N,Int}, s::IOStream) = mmap_array(T, dims, s, position(s))
45aa368 @timholy Add support for syncing mmap.
timholy authored
104 msync{T}(A::Array{T}, flags::Int) = msync(pointer(A), prod(size(A))*sizeof(T), flags)
105 msync{T}(A::Array{T}) = msync(A,MS_SYNC)
526e70d @timholy Serializable/deserializable version of a mmaparray, without transmitt…
timholy authored
106
107 # For storing information about a mmapped-array
108 type MmapArrayInfo
109 pathname::ByteString
110 eltype::Type
111 dims::Dims
112 end
Something went wrong with that request. Please try again.