github.com/primecitizens/pcz/std@v0.2.1/core/cpu/cpu_arm64_darwin.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright 2023 The Prime Citizens
     3  //
     4  // Copyright 2020 The Go Authors. All rights reserved.
     5  // Use of this source code is governed by a BSD-style
     6  // license that can be found in the LICENSE file.
     7  
     8  //go:build arm64 && darwin && !ios
     9  
    10  package cpu
    11  
    12  import (
    13  	"unsafe"
    14  )
    15  
    16  func osInit() *ARM64Features {
    17  	if sysctlEnabled("hw.optional.armv8_1_atomics\x00") {
    18  		ARM64 |= ARM64Feature_atomics
    19  	}
    20  
    21  	if sysctlEnabled("hw.optional.armv8_crc32\x00") {
    22  		ARM64 |= ARM64Feature_crc32
    23  	}
    24  
    25  	// There are no hw.optional sysctl values for the below features on Mac OS 11.0
    26  	// to detect their supported state dynamically. Assume the CPU features that
    27  	// Apple Silicon M1 supports to be available as a minimal set of features
    28  	// to all Go programs running on darwin/arm64.
    29  	ARM64 |= ARM64Feature_aes | ARM64Feature_pmull | ARM64Feature_sha1 | ARM64Feature_sha2
    30  	return &ARM64
    31  }
    32  
    33  type stringHeader struct {
    34  	str *byte
    35  	sz  int
    36  }
    37  
    38  func getsysctlbyname(name string) (ret int32, out int32) {
    39  	nout := unsafe.Sizeof(out)
    40  	ret = sysctlByName((*stringHeader)(unsafe.Pointer(&name)).str, (*byte)(unsafe.Pointer(&out)), &nout, nil, 0)
    41  	return
    42  }
    43  
    44  // we cannot call libc.SysctlByName directly due to import cycle as this package
    45  // is used in core/atomic to determine cpu features, and core/atomic is used in ffi/cgo
    46  // ffi/cgo is used in platform/libc
    47  //
    48  //go:noescape
    49  //go:linkname sysctlByName platform/libc.SysctlByName
    50  func sysctlByName(name *byte, oldp *byte, oldlenp *uintptr, newp *byte, newlen uintptr) int32
    51  
    52  func sysctlEnabled(name string) bool {
    53  	ret, value := getsysctlbyname(name)
    54  	if ret < 0 {
    55  		return false
    56  	}
    57  	return value > 0
    58  }