Skip to content

Commit

Permalink
Refactor to use provided unix functions
Browse files Browse the repository at this point in the history
golang.org/x/sys/unix provides functions for syscalls like msync that
syscall didn't previously provide. This lets us simplify a little bit
and simultaneously support more platforms that have different constant
names.
  • Loading branch information
edsrzf committed Dec 15, 2018
1 parent 0833494 commit 188cc3b
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 37 deletions.
17 changes: 9 additions & 8 deletions mmap.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,25 +81,27 @@ func (m *MMap) header() *reflect.SliceHeader {
return (*reflect.SliceHeader)(unsafe.Pointer(m))
}

func (m *MMap) addrLen() (uintptr, uintptr) {
header := m.header()
return header.Data, uintptr(header.Len)
}

// Lock keeps the mapped region in physical memory, ensuring that it will not be
// swapped out.
func (m MMap) Lock() error {
dh := m.header()
return lock(dh.Data, uintptr(dh.Len))
return m.lock()
}

// Unlock reverses the effect of Lock, allowing the mapped region to potentially
// be swapped out.
// If m is already unlocked, aan error will result.
func (m MMap) Unlock() error {
dh := m.header()
return unlock(dh.Data, uintptr(dh.Len))
return m.unlock()
}

// Flush synchronizes the mapping's contents to the file's contents on disk.
func (m MMap) Flush() error {
dh := m.header()
return flush(dh.Data, uintptr(dh.Len))
return m.flush()
}

// Unmap deletes the memory mapped region, flushes any remaining changes, and sets
Expand All @@ -109,8 +111,7 @@ func (m MMap) Flush() error {
// Unmap should only be called on the slice value that was originally returned from
// a call to Map. Calling Unmap on a derived slice may cause errors.
func (m *MMap) Unmap() error {
dh := m.header()
err := unmap(dh.Data, uintptr(dh.Len))
err := m.unmap()
*m = nil
return err
}
32 changes: 8 additions & 24 deletions mmap_unix.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,34 +34,18 @@ func mmap(len int, inprot, inflags, fd uintptr, off int64) ([]byte, error) {
return b, nil
}

func flush(addr, len uintptr) error {
_, _, errno := unix.Syscall(unix.SYS_MSYNC, addr, len, unix.MS_SYNC)
if errno != 0 {
return unix.Errno(errno)
}
return nil
func (m MMap) flush() error {
return unix.Msync([]byte(m), unix.MS_SYNC)
}

func lock(addr, len uintptr) error {
_, _, errno := unix.Syscall(unix.SYS_MLOCK, addr, len, 0)
if errno != 0 {
return unix.Errno(errno)
}
return nil
func (m MMap) lock() error {
return unix.Mlock([]byte(m))
}

func unlock(addr, len uintptr) error {
_, _, errno := unix.Syscall(unix.SYS_MUNLOCK, addr, len, 0)
if errno != 0 {
return unix.Errno(errno)
}
return nil
func (m MMap) unlock() error {
return unix.Munlock([]byte(m))
}

func unmap(addr, len uintptr) error {
_, _, errno := unix.Syscall(unix.SYS_MUNMAP, addr, len, 0)
if errno != 0 {
return unix.Errno(errno)
}
return nil
func (m MMap) unmap() error {
return unix.Munmap([]byte(m))
}
15 changes: 10 additions & 5 deletions mmap_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ func mmap(len int, prot, flags, hfile uintptr, off int64) ([]byte, error) {
return m, nil
}

func flush(addr, len uintptr) error {
func (m MMap) flush() error {
addr, len := m.addrLen()
errno := windows.FlushViewOfFile(addr, len)
if errno != nil {
return os.NewSyscallError("FlushViewOfFile", errno)
Expand All @@ -99,21 +100,25 @@ func flush(addr, len uintptr) error {
return os.NewSyscallError("FlushFileBuffers", errno)
}

func lock(addr, len uintptr) error {
func (m MMap) lock() error {
addr, len := m.addrLen()
errno := windows.VirtualLock(addr, len)
return os.NewSyscallError("VirtualLock", errno)
}

func unlock(addr, len uintptr) error {
func (m MMap) unlock() error {
addr, len := m.addrLen()
errno := windows.VirtualUnlock(addr, len)
return os.NewSyscallError("VirtualUnlock", errno)
}

func unmap(addr, len uintptr) (err error) {
err = flush(addr, len)
func (m MMap) unmap() error {
err := m.flush()
if err != nil {
return err
}

addr := m.header().Data
// Lock the UnmapViewOfFile along with the handleMap deletion.
// As soon as we unmap the view, the OS is free to give the
// same addr to another new map. We don't want another goroutine
Expand Down

0 comments on commit 188cc3b

Please sign in to comment.