mmap_linux.go raw
1 //go:build !js
2 // +build !js
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 "os"
13 "unsafe"
14
15 "golang.org/x/sys/unix"
16 )
17
18 // mmap uses the mmap system call to memory-map a file. If writable is true,
19 // memory protection of the pages is set so that they may be written to as well.
20 func mmap(fd *os.File, writable bool, size int64) ([]byte, error) {
21 mtype := unix.PROT_READ
22 if writable {
23 mtype |= unix.PROT_WRITE
24 }
25 return unix.Mmap(int(fd.Fd()), 0, int(size), mtype, unix.MAP_SHARED)
26 }
27
28 // munmap unmaps a previously mapped slice.
29 //
30 // unix.Munmap maintains an internal list of mmapped addresses, and only calls munmap
31 // if the address is present in that list. If we use mremap, this list is not updated.
32 // To bypass this, we call munmap ourselves.
33 func munmap(data []byte) error {
34 if len(data) == 0 || len(data) != cap(data) {
35 return unix.EINVAL
36 }
37 _, _, errno := unix.Syscall(
38 unix.SYS_MUNMAP,
39 uintptr(unsafe.Pointer(&data[0])),
40 uintptr(len(data)),
41 0,
42 )
43 if errno != 0 {
44 return errno
45 }
46 return nil
47 }
48
49 // madvise uses the madvise system call to give advise about the use of memory
50 // when using a slice that is memory-mapped to a file. Set the readahead flag to
51 // false if page references are expected in random order.
52 func madvise(b []byte, readahead bool) error {
53 flags := unix.MADV_NORMAL
54 if !readahead {
55 flags = unix.MADV_RANDOM
56 }
57 return unix.Madvise(b, flags)
58 }
59
60 // msync writes any modified data to persistent storage.
61 func msync(b []byte) error {
62 return unix.Msync(b, unix.MS_SYNC)
63 }
64