mmap_windows.go 1.9 KB

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