Initial commit: Go 1.23 release state
This commit is contained in:
90
src/runtime/vdso_freebsd_x86.go
Normal file
90
src/runtime/vdso_freebsd_x86.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2018 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
//go:build freebsd && (386 || amd64)
|
||||
|
||||
package runtime
|
||||
|
||||
import (
|
||||
"internal/runtime/atomic"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
const (
|
||||
_VDSO_TH_ALGO_X86_TSC = 1
|
||||
_VDSO_TH_ALGO_X86_HPET = 2
|
||||
)
|
||||
|
||||
const (
|
||||
_HPET_DEV_MAP_MAX = 10
|
||||
_HPET_MAIN_COUNTER = 0xf0 /* Main counter register */
|
||||
|
||||
hpetDevPath = "/dev/hpetX\x00"
|
||||
)
|
||||
|
||||
var hpetDevMap [_HPET_DEV_MAP_MAX]uintptr
|
||||
|
||||
//go:nosplit
|
||||
func (th *vdsoTimehands) getTSCTimecounter() uint32 {
|
||||
tsc := cputicks()
|
||||
if th.x86_shift > 0 {
|
||||
tsc >>= th.x86_shift
|
||||
}
|
||||
return uint32(tsc)
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (th *vdsoTimehands) getHPETTimecounter() (uint32, bool) {
|
||||
idx := int(th.x86_hpet_idx)
|
||||
if idx >= len(hpetDevMap) {
|
||||
return 0, false
|
||||
}
|
||||
|
||||
p := atomic.Loaduintptr(&hpetDevMap[idx])
|
||||
if p == 0 {
|
||||
systemstack(func() { initHPETTimecounter(idx) })
|
||||
p = atomic.Loaduintptr(&hpetDevMap[idx])
|
||||
}
|
||||
if p == ^uintptr(0) {
|
||||
return 0, false
|
||||
}
|
||||
return *(*uint32)(unsafe.Pointer(p + _HPET_MAIN_COUNTER)), true
|
||||
}
|
||||
|
||||
//go:systemstack
|
||||
func initHPETTimecounter(idx int) {
|
||||
const digits = "0123456789"
|
||||
|
||||
var devPath [len(hpetDevPath)]byte
|
||||
copy(devPath[:], hpetDevPath)
|
||||
devPath[9] = digits[idx]
|
||||
|
||||
fd := open(&devPath[0], 0 /* O_RDONLY */ |_O_CLOEXEC, 0)
|
||||
if fd < 0 {
|
||||
atomic.Casuintptr(&hpetDevMap[idx], 0, ^uintptr(0))
|
||||
return
|
||||
}
|
||||
|
||||
addr, mmapErr := mmap(nil, physPageSize, _PROT_READ, _MAP_SHARED, fd, 0)
|
||||
closefd(fd)
|
||||
newP := uintptr(addr)
|
||||
if mmapErr != 0 {
|
||||
newP = ^uintptr(0)
|
||||
}
|
||||
if !atomic.Casuintptr(&hpetDevMap[idx], 0, newP) && mmapErr == 0 {
|
||||
munmap(addr, physPageSize)
|
||||
}
|
||||
}
|
||||
|
||||
//go:nosplit
|
||||
func (th *vdsoTimehands) getTimecounter() (uint32, bool) {
|
||||
switch th.algo {
|
||||
case _VDSO_TH_ALGO_X86_TSC:
|
||||
return th.getTSCTimecounter(), true
|
||||
case _VDSO_TH_ALGO_X86_HPET:
|
||||
return th.getHPETTimecounter()
|
||||
default:
|
||||
return 0, false
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user