1
0
Fork 0
forked from judah/xx
xx/mem/mem_unix.go

68 lines
1.2 KiB
Go

//go:build unix
package mem
import (
"syscall"
"unsafe"
)
func reserve(total_address_space uintptr) ([]byte, error) {
data, err := syscall.Mmap(-1, 0, int(total_address_space), syscall.PROT_NONE, syscall.MAP_PRIVATE|syscall.MAP_ANON)
if err != nil {
return nil, err
}
return data, nil
}
func release(reserved []byte) error {
return syscall.Munmap(reserved)
}
func commit(reserved []byte, access Access) error {
return syscall.Mprotect(reserved, access_to_prot(access))
}
func decommit(committed []byte) (err error) {
err = syscall.Mprotect(committed, syscall.PROT_NONE)
if err != nil {
return
}
return madvise(committed, syscall.MADV_DONTNEED)
}
var _zero uintptr
func madvise(b []byte, advice int) (err error) {
var _p0 unsafe.Pointer
if len(b) > 0 {
_p0 = unsafe.Pointer(&b[0])
} else {
_p0 = unsafe.Pointer(&_zero)
}
_, _, e := syscall.Syscall(syscall.SYS_MADVISE, uintptr(_p0), uintptr(len(b)), uintptr(advice))
if e != 0 {
err = syscall.Errno(e)
}
return
}
func access_to_prot(access Access) (prot int) {
prot = syscall.PROT_NONE
if access&AccessRead != 0 {
prot |= syscall.PROT_READ
}
if access&AccessWrite != 0 {
prot |= syscall.PROT_WRITE
}
if access&AccessExecute != 0 {
prot |= syscall.PROT_EXEC
}
return
}