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