mmap_linux.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. //go:build !js
  2. // +build !js
  3. /*
  4. * SPDX-FileCopyrightText: © Hypermode Inc. <hello@hypermode.com>
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. package z
  8. import (
  9. "os"
  10. "unsafe"
  11. "golang.org/x/sys/unix"
  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. // munmap unmaps a previously mapped slice.
  23. //
  24. // unix.Munmap maintains an internal list of mmapped addresses, and only calls munmap
  25. // if the address is present in that list. If we use mremap, this list is not updated.
  26. // To bypass this, we call munmap ourselves.
  27. func munmap(data []byte) error {
  28. if len(data) == 0 || len(data) != cap(data) {
  29. return unix.EINVAL
  30. }
  31. _, _, errno := unix.Syscall(
  32. unix.SYS_MUNMAP,
  33. uintptr(unsafe.Pointer(&data[0])),
  34. uintptr(len(data)),
  35. 0,
  36. )
  37. if errno != 0 {
  38. return errno
  39. }
  40. return nil
  41. }
  42. // madvise uses the madvise system call to give advise about the use of memory
  43. // when using a slice that is memory-mapped to a file. Set the readahead flag to
  44. // false if page references are expected in random order.
  45. func madvise(b []byte, readahead bool) error {
  46. flags := unix.MADV_NORMAL
  47. if !readahead {
  48. flags = unix.MADV_RANDOM
  49. }
  50. return unix.Madvise(b, flags)
  51. }
  52. // msync writes any modified data to persistent storage.
  53. func msync(b []byte) error {
  54. return unix.Msync(b, unix.MS_SYNC)
  55. }