File: buffer_mmap.go

package info (click to toggle)
golang-github-segmentio-asm 1.2.0%2Bgit20231107.1cfacc8-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 932 kB
  • sloc: asm: 6,093; makefile: 32
file content (56 lines) | stat: -rw-r--r-- 1,162 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
//go:build !purego && (aix || android || darwin || dragonfly || freebsd || illumos || ios || linux || netbsd || openbsd || plan9 || solaris)
// +build !purego
// +build aix android darwin dragonfly freebsd illumos ios linux netbsd openbsd plan9 solaris

// TODO: replace the above with go:build unix once Go 1.19 is the lowest
// supported version

package buffer

import (
	"golang.org/x/sys/unix"
)

type Buffer struct {
	n    int
	pg   int
	mmap []byte
}

func New(n int) (Buffer, error) {
	pg := unix.Getpagesize()
	full := ((n+(pg-1))/pg + 2) * pg

	b, err := unix.Mmap(-1, 0, full, unix.PROT_NONE, unix.MAP_ANON|unix.MAP_PRIVATE)
	if err != nil {
		return Buffer{}, err
	}

	if n > 0 {
		err = unix.Mprotect(b[pg:full-pg], unix.PROT_READ|unix.PROT_WRITE)
		if err != nil {
			unix.Munmap(b)
			return Buffer{}, err
		}
	}

	return Buffer{
		n:    n,
		pg:   pg,
		mmap: b,
	}, nil
}

func (a *Buffer) ProtectHead() []byte {
	head := a.pg
	return a.mmap[head : head+a.n : head+a.n]
}

func (a *Buffer) ProtectTail() []byte {
	tail := len(a.mmap) - a.pg - a.n
	return a.mmap[tail : tail+a.n : tail+a.n]
}

func (a *Buffer) Release() {
	unix.Munmap(a.mmap)
}