Skip to content

Commit

Permalink
fix Mmap.sync! for array mapped from an offset
Browse files Browse the repository at this point in the history
This fixes error when calling `Mmap.sync!` on an array that is not memory mapped from a pagesized offset of a file.

````
julia> using Base.Mmap

julia> f = open("arrayfile", "r+");

julia> A = Mmap.mmap(f, Vector{Int64}, (200,), 0);

julia> Mmap.sync!(A)

julia> B = Mmap.mmap(f, Vector{Int64}, (200,), 8);

julia> Mmap.sync!(B)
ERROR: SystemError: msync: Invalid argument
 [inlined code] from ./int.jl:33
 in sync!(Base.Mmap.#sync!, Array{Int64,1}, Int64) at ./mmap.jl:207 (repeats 2 times)
 in eval at ./boot.jl:267
````

Since `Mmap.mmap` maps from the beginning of a page boundary, `pointer(A)` is not at the page boundary when an offset is provided.
But since the pointer returned from `mmap` is aligned at page boundary, `sync!` now recalculates the offset before calling `msync!`.

````
julia> using Base.Mmap

julia> f = open("arrayfile", "r+");

julia> B = Mmap.mmap(f, Vector{Int64}, (200,), 8);

julia> Mmap.sync!(B)
````
  • Loading branch information
tanmaykm committed Feb 1, 2016
1 parent 2bb94d6 commit 75ebbca
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 2 deletions.
6 changes: 4 additions & 2 deletions base/mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -204,9 +204,11 @@ const MS_INVALIDATE = 2
const MS_SYNC = 4

function sync!{T}(m::Array{T}, flags::Integer=MS_SYNC)
@unix_only systemerror("msync", ccall(:msync, Cint, (Ptr{Void}, Csize_t, Cint), pointer(m), length(m)*sizeof(T), flags) != 0)
offset = rem(UInt(pointer(m)), PAGESIZE)
ptr = pointer(m) - offset
@unix_only systemerror("msync", ccall(:msync, Cint, (Ptr{Void}, Csize_t, Cint), ptr, length(m)*sizeof(T), flags) != 0)
@windows_only systemerror("could not FlushViewOfFile: $(Libc.FormatMessage())",
ccall(:FlushViewOfFile, stdcall, Cint, (Ptr{Void}, Csize_t), pointer(m), length(m)) == 0)
ccall(:FlushViewOfFile, stdcall, Cint, (Ptr{Void}, Csize_t), ptr, length(m)) == 0)
end
sync!(B::BitArray, flags::Integer=MS_SYNC) = sync!(B.chunks, flags)

Expand Down
11 changes: 11 additions & 0 deletions test/mmap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -278,3 +278,14 @@ n = similar(m, 12)
@test length(n) == 12
@test size(n) == (12,)
finalize(m); m = nothing; gc()

# test #14885
file = tempname()
touch(file)
open(file, "r+") do s
A = Mmap.mmap(s, Vector{UInt8}, (10,), 0);
Mmap.sync!(A)
A = Mmap.mmap(s, Vector{UInt8}, (10,), 1);
Mmap.sync!(A)
end
rm(file)

0 comments on commit 75ebbca

Please sign in to comment.