github.com/zhiqiangxu/util@v0.0.0-20230112053021-0a7aee056cd5/mmap.go (about) 1 // +build !windows 2 3 package util 4 5 import ( 6 "os" 7 "syscall" 8 "unsafe" 9 10 "golang.org/x/sys/unix" 11 ) 12 13 // Mmap uses the mmap system call to memory-map a file. If writable is true, 14 // memory protection of the pages is set so that they may be written to as well. 15 func Mmap(fd *os.File, writable bool, size int64) ([]byte, error) { 16 mtype := unix.PROT_READ 17 if writable { 18 mtype |= unix.PROT_WRITE 19 } 20 return unix.Mmap(int(fd.Fd()), 0, int(size), mtype, unix.MAP_SHARED) 21 } 22 23 // Munmap unmaps a previously mapped slice. 24 func Munmap(b []byte) error { 25 return unix.Munmap(b) 26 } 27 28 // Madvise uses the madvise system call to give advise about the use of memory 29 // when using a slice that is memory-mapped to a file. Set the readahead flag to 30 // false if page references are expected in random order. 31 func Madvise(b []byte, readahead bool) error { 32 flags := unix.MADV_NORMAL 33 if !readahead { 34 flags = unix.MADV_RANDOM 35 } 36 return madvise(b, flags) 37 } 38 39 // This is required because the unix package does not support the madvise system call on OS X. 40 func madvise(b []byte, advice int) (err error) { 41 _, _, e1 := syscall.Syscall(syscall.SYS_MADVISE, uintptr(unsafe.Pointer(&b[0])), 42 uintptr(len(b)), uintptr(advice)) 43 if e1 != 0 { 44 err = e1 45 } 46 return 47 } 48 49 // MSync for flush mmaped bytes 50 func MSync(b []byte, length int64, flags int) (err error) { 51 _, _, e1 := syscall.Syscall(syscall.SYS_MSYNC, 52 uintptr(unsafe.Pointer(&b[0])), uintptr(length), uintptr(flags)) 53 if e1 != 0 { 54 err = e1 55 } 56 57 return 58 } 59 60 // MLock mmaped bytes 61 func MLock(b []byte, length int) (err error) { 62 _, _, e1 := syscall.Syscall(syscall.SYS_MLOCK, 63 uintptr(unsafe.Pointer(&b[0])), uintptr(length), 0) 64 if e1 != 0 { 65 err = e1 66 } 67 68 return 69 } 70 71 // MUnlock mmaped bytes 72 func MUnlock(b []byte, length int) (err error) { 73 _, _, e1 := syscall.Syscall(syscall.SYS_MUNLOCK, 74 uintptr(unsafe.Pointer(&b[0])), uintptr(length), 0) 75 if e1 != 0 { 76 err = e1 77 } 78 79 return 80 }