mmap_windows.go raw
1 //go:build windows
2 // +build windows
3
4 /*
5 * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
6 * SPDX-License-Identifier: Apache-2.0
7 */
8
9 package z
10
11 import (
12 "fmt"
13 "os"
14 "syscall"
15 "unsafe"
16 )
17
18 func mmap(fd *os.File, write bool, size int64) ([]byte, error) {
19 protect := syscall.PAGE_READONLY
20 access := syscall.FILE_MAP_READ
21
22 if write {
23 protect = syscall.PAGE_READWRITE
24 access = syscall.FILE_MAP_WRITE
25 }
26 fi, err := fd.Stat()
27 if err != nil {
28 return nil, err
29 }
30
31 // In windows, we cannot mmap a file more than it's actual size.
32 // So truncate the file to the size of the mmap.
33 if fi.Size() < size {
34 if err := fd.Truncate(size); err != nil {
35 return nil, fmt.Errorf("truncate: %s", err)
36 }
37 }
38
39 // Open a file mapping handle.
40 sizelo := uint32(size >> 32)
41 sizehi := uint32(size) & 0xffffffff
42
43 handler, err := syscall.CreateFileMapping(syscall.Handle(fd.Fd()), nil,
44 uint32(protect), sizelo, sizehi, nil)
45 if err != nil {
46 return nil, os.NewSyscallError("CreateFileMapping", err)
47 }
48
49 // Create the memory map.
50 addr, err := syscall.MapViewOfFile(handler, uint32(access), 0, 0, uintptr(size))
51 if addr == 0 {
52 return nil, os.NewSyscallError("MapViewOfFile", err)
53 }
54
55 // Close mapping handle.
56 if err := syscall.CloseHandle(syscall.Handle(handler)); err != nil {
57 return nil, os.NewSyscallError("CloseHandle", err)
58 }
59
60 // Slice memory layout
61 // Copied this snippet from golang/sys package
62 var sl = struct {
63 addr uintptr
64 len int
65 cap int
66 }{addr, int(size), int(size)}
67
68 // Use unsafe to turn sl into a []byte.
69 data := *(*[]byte)(unsafe.Pointer(&sl))
70
71 return data, nil
72 }
73
74 func munmap(b []byte) error {
75 return syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&b[0])))
76 }
77
78 func madvise(b []byte, readahead bool) error {
79 // Do Nothing. We don’t care about this setting on Windows
80 return nil
81 }
82
83 func msync(b []byte) error {
84 // TODO: Figure out how to do msync on Windows.
85 return nil
86 }
87