github.com/etecs-ru/ristretto@v0.9.1/z/mmap_windows.go (about) 1 //go:build windows 2 // +build windows 3 4 /* 5 * Copyright 2019 Dgraph Labs, Inc. and Contributors 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 */ 19 20 package z 21 22 import ( 23 "fmt" 24 "os" 25 "syscall" 26 "unsafe" 27 ) 28 29 func mmap(fd *os.File, write bool, size int64) ([]byte, error) { 30 protect := syscall.PAGE_READONLY 31 access := syscall.FILE_MAP_READ 32 33 if write { 34 protect = syscall.PAGE_READWRITE 35 access = syscall.FILE_MAP_WRITE 36 } 37 fi, err := fd.Stat() 38 if err != nil { 39 return nil, err 40 } 41 42 // In windows, we cannot mmap a file more than it's actual size. 43 // So truncate the file to the size of the mmap. 44 if fi.Size() < size { 45 if err := fd.Truncate(size); err != nil { 46 return nil, fmt.Errorf("truncate: %s", err) 47 } 48 } 49 50 // Open a file mapping handle. 51 sizelo := uint32(size >> 32) 52 sizehi := uint32(size) & 0xffffffff 53 54 handler, err := syscall.CreateFileMapping(syscall.Handle(fd.Fd()), nil, 55 uint32(protect), sizelo, sizehi, nil) 56 if err != nil { 57 return nil, os.NewSyscallError("CreateFileMapping", err) 58 } 59 60 // Create the memory map. 61 addr, err := syscall.MapViewOfFile(handler, uint32(access), 0, 0, uintptr(size)) 62 if addr == 0 { 63 return nil, os.NewSyscallError("MapViewOfFile", err) 64 } 65 66 // Close mapping handle. 67 if err := syscall.CloseHandle(syscall.Handle(handler)); err != nil { 68 return nil, os.NewSyscallError("CloseHandle", err) 69 } 70 71 // Slice memory layout 72 // Copied this snippet from golang/sys package 73 sl := struct { 74 addr uintptr 75 len int 76 cap int 77 }{addr, int(size), int(size)} 78 79 // Use unsafe to turn sl into a []byte. 80 data := *(*[]byte)(unsafe.Pointer(&sl)) 81 82 return data, nil 83 } 84 85 func munmap(b []byte) error { 86 return syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&b[0]))) 87 } 88 89 func madvise(b []byte, readahead bool) error { 90 // Do Nothing. We don’t care about this setting on Windows 91 return nil 92 } 93 94 func msync(b []byte) error { 95 return syscall.FlushViewOfFile(uintptr(unsafe.Pointer(&b[0])), uintptr(len(b))) 96 }