// Copyright 2011 Evan Shaw. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE-MMAP-GO file.

// +build darwin dragonfly freebsd linux openbsd solaris netbsd

// Modifications (c) 2017 The Memory Authors.

package memory // import "modernc.org/memory"

import (
	
	
	
)

const pageSizeLog = 20

var (
	osPageMask = osPageSize - 1
	osPageSize = os.Getpagesize()
)

func ( uintptr,  int) error {
	, ,  := syscall.Syscall(syscall.SYS_MUNMAP, , uintptr(), 0)
	if  != 0 {
		return 
	}

	return nil
}

// pageSize aligned.
func ( int) (uintptr, int, error) {
	 = roundup(, osPageSize)
	,  := syscall.Mmap(-1, 0, +pageSize, syscall.PROT_READ|syscall.PROT_WRITE, syscall.MAP_SHARED|syscall.MAP_ANON)
	if  != nil {
		return 0, 0, 
	}

	 := len()
	 := uintptr(unsafe.Pointer(&[0]))
	if &uintptr(osPageMask) != 0 {
		panic("internal error")
	}

	 := int() & pageMask
	if  != 0 {
		 := pageSize - 
		if  := unmap(, );  != nil {
			return 0, 0, 
		}

		 -= 
		 += uintptr()
	}

	if &uintptr(pageMask) != 0 {
		panic("internal error")
	}

	if - != 0 {
		if  := unmap(+uintptr(), -);  != nil {
			return 0, 0, 
		}
	}

	return , , nil
}