github.com/c0deoo1/golang1.5@v0.0.0-20220525150107-c87c805d4593/src/runtime/mem_bsd.go (about)

     1  // Copyright 2010 The Go Authors.  All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build dragonfly freebsd nacl netbsd openbsd solaris
     6  
     7  package runtime
     8  
     9  import "unsafe"
    10  
    11  // Don't split the stack as this function may be invoked without a valid G,
    12  // which prevents us from allocating more stack.
    13  //go:nosplit
    14  func sysAlloc(n uintptr, sysStat *uint64) unsafe.Pointer {
    15  	v := unsafe.Pointer(mmap(nil, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_PRIVATE, -1, 0))
    16  	if uintptr(v) < 4096 {
    17  		return nil
    18  	}
    19  	mSysStatInc(sysStat, n)
    20  	return v
    21  }
    22  
    23  func sysUnused(v unsafe.Pointer, n uintptr) {
    24  	madvise(v, n, _MADV_FREE)
    25  }
    26  
    27  func sysUsed(v unsafe.Pointer, n uintptr) {
    28  }
    29  
    30  // Don't split the stack as this function may be invoked without a valid G,
    31  // which prevents us from allocating more stack.
    32  //go:nosplit
    33  func sysFree(v unsafe.Pointer, n uintptr, sysStat *uint64) {
    34  	mSysStatDec(sysStat, n)
    35  	munmap(v, n)
    36  }
    37  
    38  func sysFault(v unsafe.Pointer, n uintptr) {
    39  	mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE|_MAP_FIXED, -1, 0)
    40  }
    41  
    42  func sysReserve(v unsafe.Pointer, n uintptr, reserved *bool) unsafe.Pointer {
    43  	// On 64-bit, people with ulimit -v set complain if we reserve too
    44  	// much address space.  Instead, assume that the reservation is okay
    45  	// and check the assumption in SysMap.
    46  	if ptrSize == 8 && uint64(n) > 1<<32 || goos_nacl != 0 {
    47  		*reserved = false
    48  		return v
    49  	}
    50  
    51  	p := unsafe.Pointer(mmap(v, n, _PROT_NONE, _MAP_ANON|_MAP_PRIVATE, -1, 0))
    52  	if uintptr(p) < 4096 {
    53  		return nil
    54  	}
    55  	*reserved = true
    56  	return p
    57  }
    58  
    59  func sysMap(v unsafe.Pointer, n uintptr, reserved bool, sysStat *uint64) {
    60  	const _ENOMEM = 12
    61  
    62  	mSysStatInc(sysStat, n)
    63  
    64  	// On 64-bit, we don't actually have v reserved, so tread carefully.
    65  	if !reserved {
    66  		flags := int32(_MAP_ANON | _MAP_PRIVATE)
    67  		if GOOS == "dragonfly" {
    68  			// TODO(jsing): For some reason DragonFly seems to return
    69  			// memory at a different address than we requested, even when
    70  			// there should be no reason for it to do so. This can be
    71  			// avoided by using MAP_FIXED, but I'm not sure we should need
    72  			// to do this - we do not on other platforms.
    73  			flags |= _MAP_FIXED
    74  		}
    75  		p := mmap(v, n, _PROT_READ|_PROT_WRITE, flags, -1, 0)
    76  		if uintptr(p) == _ENOMEM {
    77  			throw("runtime: out of memory")
    78  		}
    79  		if p != v {
    80  			print("runtime: address space conflict: map(", v, ") = ", p, "\n")
    81  			throw("runtime: address space conflict")
    82  		}
    83  		return
    84  	}
    85  
    86  	p := mmap(v, n, _PROT_READ|_PROT_WRITE, _MAP_ANON|_MAP_FIXED|_MAP_PRIVATE, -1, 0)
    87  	if uintptr(p) == _ENOMEM {
    88  		throw("runtime: out of memory")
    89  	}
    90  	if p != v {
    91  		throw("runtime: cannot map pages in arena address space")
    92  	}
    93  }