gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

mmap_illumos_amd64.go (2188B)


      1 // Copyright 2011 Evan Shaw. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE-MMAP-GO file.
      4 
      5 // Modifications (c) 2022 The Memory Authors.
      6 
      7 package memory // import "modernc.org/memory"
      8 
      9 import (
     10 	"os"
     11 	"syscall"
     12 	_ "unsafe"
     13 )
     14 
     15 const (
     16 	pageSizeLog = 20
     17 
     18 	// $ find /usr/include -name syscall.h
     19 	// /usr/include/sys/syscall.h
     20 	// $ grep -ni munmap /usr/include/sys/syscall.h
     21 	// 293:#define     SYS_munmap      117
     22 	// $ grep -ni mmap /usr/include/sys/syscall.h
     23 	// 291:#define	SYS_mmap	115
     24 	// 303:#define	SYS_mmapobj	127
     25 	// 442:#define	SYS_mmap64		214
     26 	// $
     27 	// $ uname -a
     28 	// SunOS omnios64 5.11 omnios-r151044-d3b715b9d1 i86pc i386 i86pc
     29 	// $
     30 	sys_MUNMAP = 117
     31 	sys_MMAP   = 214
     32 )
     33 
     34 var (
     35 	osPageMask = osPageSize - 1
     36 	osPageSize = os.Getpagesize()
     37 )
     38 
     39 //go:linkname mmapSyscall syscall.mmap
     40 func mmapSyscall(addr uintptr, length uintptr, prot int, flags int, fd int, offset int64) (xaddr uintptr, err error)
     41 
     42 func unmap(addr uintptr, size int) error {
     43 	_, _, errno := syscall.Syscall(sys_MUNMAP, addr, uintptr(size), 0)
     44 	if errno != 0 {
     45 		return errno
     46 	}
     47 
     48 	return nil
     49 }
     50 
     51 // pageSize aligned.
     52 func mmap(size int) (uintptr, int, error) {
     53 	size = roundup(size, osPageSize)
     54 	// The actual mmap syscall varies by architecture. mmapSyscall provides same
     55 	// functionality as the unexported funtion syscall.mmap and is declared in
     56 	// mmap_*_*.go and mmap_fallback.go. To add support for a new architecture,
     57 	// check function mmap in src/syscall/syscall_*_*.go or
     58 	// src/syscall/zsyscall_*_*.go in Go's source code.
     59 	p, err := mmapSyscall(0, uintptr(size+pageSize), syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_PRIVATE|syscall.MAP_ANON, -1, 0)
     60 	if err != nil {
     61 		return 0, 0, err
     62 	}
     63 
     64 	n := size + pageSize
     65 	if p&uintptr(osPageMask) != 0 {
     66 		panic("internal error")
     67 	}
     68 
     69 	mod := int(p) & pageMask
     70 	if mod != 0 {
     71 		m := pageSize - mod
     72 		if err := unmap(p, m); err != nil {
     73 			return 0, 0, err
     74 		}
     75 
     76 		n -= m
     77 		p += uintptr(m)
     78 	}
     79 
     80 	if p&uintptr(pageMask) != 0 {
     81 		panic("internal error")
     82 	}
     83 
     84 	if n-size != 0 {
     85 		if err := unmap(p+uintptr(size), n-size); err != nil {
     86 			return 0, 0, err
     87 		}
     88 	}
     89 
     90 	return p, size, nil
     91 }